@epublishing/grunt-epublishing 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/configure-webpack.js +96 -67
- package/lib/init-jade-config.js +1 -6
- package/node-upgrade.md +368 -0
- package/package.json +17 -8
- package/tasks/jade.js +16 -0
- package/tasks/npm-install.js +1 -1
- package/tasks/sass.js +38 -0
- package/lib/configure-sass.js +0 -24
package/lib/configure-webpack.js
CHANGED
|
@@ -3,25 +3,26 @@
|
|
|
3
3
|
* targets, including loaders and output plugins.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const os
|
|
9
|
-
const fs
|
|
10
|
-
const path
|
|
11
|
-
const webpack
|
|
12
|
-
const BundleAnalyzerPlugin =
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const os = require("os");
|
|
9
|
+
const fs = require("fs");
|
|
10
|
+
const path = require("path");
|
|
11
|
+
const webpack = require("webpack");
|
|
12
|
+
const BundleAnalyzerPlugin =
|
|
13
|
+
require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
|
|
14
|
+
const CompressionPlugin = require("compression-webpack-plugin");
|
|
15
|
+
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
|
|
16
|
+
const lodashDir = path.dirname(require.resolve("lodash"));
|
|
17
|
+
const moduleDir = path.dirname(lodashDir);
|
|
17
18
|
|
|
18
19
|
module.exports = function configureWebpack(grunt, config) {
|
|
19
|
-
const { NODE_ENV =
|
|
20
|
-
const watch
|
|
21
|
-
const verbose
|
|
22
|
-
const noMinify = !!grunt.option(
|
|
23
|
-
const analyze
|
|
24
|
-
const lint
|
|
20
|
+
const { NODE_ENV = "development" } = process.env;
|
|
21
|
+
const watch = !!grunt.option("watch");
|
|
22
|
+
const verbose = !!grunt.option("verbose");
|
|
23
|
+
const noMinify = !!grunt.option("no-minify");
|
|
24
|
+
const analyze = !!grunt.option("analyze");
|
|
25
|
+
const lint = NODE_ENV === "test" || !!grunt.option("lint");
|
|
25
26
|
|
|
26
27
|
for (const target in config.webpack) {
|
|
27
28
|
const targetConfig = config.webpack[target];
|
|
@@ -42,45 +43,67 @@ module.exports = function configureWebpack(grunt, config) {
|
|
|
42
43
|
// This prevents Webpack from loading every single locale definition file that Moment.js provides.
|
|
43
44
|
// 99% of the time we only care about formatting dates in US English, so we have no need for i.e.
|
|
44
45
|
// the preferred date formats of Esperanto-speaking residents of Papua New Guinea. American cultural hedgemony FTW!
|
|
45
|
-
const momentLocales = new webpack.ContextReplacementPlugin(
|
|
46
|
+
const momentLocales = new webpack.ContextReplacementPlugin(
|
|
47
|
+
/moment[/\\]locale$/,
|
|
48
|
+
/en/
|
|
49
|
+
);
|
|
46
50
|
|
|
47
|
-
let plugins = [
|
|
51
|
+
let plugins = [environmentVars, momentLocales];
|
|
48
52
|
|
|
49
53
|
if (!config.babelLoader) {
|
|
50
|
-
config.babelLoader = {
|
|
54
|
+
config.babelLoader = {
|
|
55
|
+
exceptions: [],
|
|
56
|
+
exclude: /(node_modules|bower_components)/,
|
|
57
|
+
};
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
const babelExclude = config.babelLoader.exclude;
|
|
54
|
-
const babelExceptions = config.babelLoader.exceptions.map(
|
|
61
|
+
const babelExceptions = config.babelLoader.exceptions.map(
|
|
62
|
+
(mod) => new RegExp(`node_modules/${mod}/(.+)\\.js$`)
|
|
63
|
+
);
|
|
55
64
|
|
|
56
|
-
targetConfig.watch
|
|
57
|
-
targetConfig.keepalive
|
|
58
|
-
targetConfig.stats.modules
|
|
59
|
-
targetConfig.stats.reasons
|
|
60
|
-
targetConfig.profile
|
|
65
|
+
targetConfig.watch = watch;
|
|
66
|
+
targetConfig.keepalive = watch || analyze;
|
|
67
|
+
targetConfig.stats.modules = verbose;
|
|
68
|
+
targetConfig.stats.reasons = verbose;
|
|
69
|
+
targetConfig.profile = analyze;
|
|
61
70
|
|
|
62
71
|
// Tell babel-plugin-lodash where to find modularized Lo-Dash functions:
|
|
63
72
|
targetConfig.resolve.alias.lodash = lodashDir;
|
|
64
73
|
|
|
65
74
|
const babelOptions = {
|
|
66
75
|
presets: [
|
|
67
|
-
[
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
[
|
|
77
|
+
require.resolve("@epublishing/babel-preset-epublishing"),
|
|
78
|
+
{
|
|
79
|
+
lodash: { cwd: moduleDir },
|
|
80
|
+
env: {
|
|
81
|
+
modules: false,
|
|
82
|
+
},
|
|
83
|
+
minify: false,
|
|
71
84
|
},
|
|
72
|
-
|
|
73
|
-
}],
|
|
85
|
+
],
|
|
74
86
|
],
|
|
75
|
-
|
|
87
|
+
plugins: [
|
|
88
|
+
[
|
|
89
|
+
require.resolve("babel-plugin-transform-react-jsx"),
|
|
90
|
+
{
|
|
91
|
+
pragma: "h",
|
|
92
|
+
// pragmaFrag: "Fragment",
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
],
|
|
96
|
+
};
|
|
76
97
|
|
|
77
98
|
const rules = [
|
|
78
99
|
{
|
|
79
100
|
test: /\.jsx?$/,
|
|
80
|
-
loader:
|
|
101
|
+
loader: "babel-loader",
|
|
81
102
|
exclude: (input) => {
|
|
82
103
|
// Check whether the asset has a matching exclusion exception pattern and allow it to transpile if it does:
|
|
83
|
-
const isException = babelExceptions.some((pattern) =>
|
|
104
|
+
const isException = babelExceptions.some((pattern) =>
|
|
105
|
+
pattern.test(input)
|
|
106
|
+
);
|
|
84
107
|
if (isException) return !isException;
|
|
85
108
|
|
|
86
109
|
// Test asset against the default exclusion pattern and return result:
|
|
@@ -93,44 +116,43 @@ module.exports = function configureWebpack(grunt, config) {
|
|
|
93
116
|
exclude: /node_modules/,
|
|
94
117
|
use: [
|
|
95
118
|
{
|
|
96
|
-
loader:
|
|
119
|
+
loader: "babel-loader",
|
|
97
120
|
options: babelOptions,
|
|
98
121
|
},
|
|
99
122
|
{
|
|
100
|
-
loader:
|
|
123
|
+
loader: "ts-loader",
|
|
101
124
|
},
|
|
102
125
|
],
|
|
103
126
|
},
|
|
104
127
|
{
|
|
105
128
|
test: /\.css$/,
|
|
106
|
-
use: [
|
|
107
|
-
'style-loader',
|
|
108
|
-
'css-loader',
|
|
109
|
-
],
|
|
129
|
+
use: ["style-loader", "css-loader"],
|
|
110
130
|
},
|
|
111
131
|
{
|
|
112
|
-
test: [
|
|
113
|
-
loader:
|
|
132
|
+
test: [/\.svg$/, /\.jpe?g$/, /\.gif$/, /\.png$/],
|
|
133
|
+
loader: "file-loader",
|
|
114
134
|
},
|
|
115
135
|
];
|
|
116
136
|
|
|
117
137
|
if (lint) {
|
|
118
|
-
const localEslintConfig = path.join(process.cwd(),
|
|
119
|
-
const globalEslintConfig = path.resolve(__dirname,
|
|
120
|
-
const eslintConfig = fs.existsSync(localEslintConfig)
|
|
138
|
+
const localEslintConfig = path.join(process.cwd(), ".eslintrc");
|
|
139
|
+
const globalEslintConfig = path.resolve(__dirname, "../.eslintrc");
|
|
140
|
+
const eslintConfig = fs.existsSync(localEslintConfig)
|
|
141
|
+
? localEslintConfig
|
|
142
|
+
: globalEslintConfig;
|
|
121
143
|
|
|
122
144
|
rules.push({
|
|
123
|
-
enforce:
|
|
145
|
+
enforce: "pre",
|
|
124
146
|
test: /\.js$/,
|
|
125
147
|
exclude: /(node_modules|bower_components|public|vendor)/,
|
|
126
|
-
loader:
|
|
148
|
+
loader: "eslint-loader",
|
|
127
149
|
options: {
|
|
128
150
|
configFile: eslintConfig,
|
|
129
|
-
formatter: require(
|
|
151
|
+
formatter: require("eslint-friendly-formatter"),
|
|
130
152
|
failOnError: true,
|
|
131
153
|
outputReport: {
|
|
132
|
-
filePath:
|
|
133
|
-
formatter: require(
|
|
154
|
+
filePath: "eslint.xml",
|
|
155
|
+
formatter: require("eslint/lib/formatters/junit"),
|
|
134
156
|
},
|
|
135
157
|
},
|
|
136
158
|
});
|
|
@@ -140,14 +162,14 @@ module.exports = function configureWebpack(grunt, config) {
|
|
|
140
162
|
|
|
141
163
|
if (analyze) {
|
|
142
164
|
const bundleAnalyzer = new BundleAnalyzerPlugin({
|
|
143
|
-
analyzerMode:
|
|
144
|
-
analyzerHost:
|
|
145
|
-
analyzerPort:
|
|
146
|
-
reportFilename:
|
|
147
|
-
defaultSizes:
|
|
165
|
+
analyzerMode: "server",
|
|
166
|
+
analyzerHost: "127.0.0.1",
|
|
167
|
+
analyzerPort: "8888",
|
|
168
|
+
reportFilename: "webpack-analysis.html",
|
|
169
|
+
defaultSizes: "parsed",
|
|
148
170
|
openAnalyzer: true,
|
|
149
171
|
generateStatsFile: true,
|
|
150
|
-
statsFilename:
|
|
172
|
+
statsFilename: "webpack.stats.json",
|
|
151
173
|
statsOptions: { chunkModules: true },
|
|
152
174
|
});
|
|
153
175
|
plugins.push(bundleAnalyzer);
|
|
@@ -162,17 +184,21 @@ module.exports = function configureWebpack(grunt, config) {
|
|
|
162
184
|
const { uglifyConfig = {} } = targetConfig;
|
|
163
185
|
delete targetConfig.uglifyConfig;
|
|
164
186
|
|
|
165
|
-
plugins.push(
|
|
187
|
+
plugins.push(
|
|
188
|
+
new UglifyJsPlugin(Object.assign({}, uglifyDefaults, uglifyConfig))
|
|
189
|
+
);
|
|
166
190
|
}
|
|
167
191
|
|
|
168
|
-
if (NODE_ENV ===
|
|
169
|
-
plugins.push(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
192
|
+
if (NODE_ENV === "production") {
|
|
193
|
+
plugins.push(
|
|
194
|
+
new CompressionPlugin({
|
|
195
|
+
asset: "[path].gz",
|
|
196
|
+
algorithm: "gzip",
|
|
197
|
+
test: /\.js$/,
|
|
198
|
+
threshold: 10240,
|
|
199
|
+
minRatio: 0.8,
|
|
200
|
+
})
|
|
201
|
+
);
|
|
176
202
|
}
|
|
177
203
|
|
|
178
204
|
if (Array.isArray(targetConfig.appendPlugins)) {
|
|
@@ -182,7 +208,10 @@ module.exports = function configureWebpack(grunt, config) {
|
|
|
182
208
|
|
|
183
209
|
targetConfig.plugins = plugins;
|
|
184
210
|
|
|
185
|
-
if (
|
|
211
|
+
if (
|
|
212
|
+
targetConfig.customize &&
|
|
213
|
+
typeof targetConfig.customize === "function"
|
|
214
|
+
) {
|
|
186
215
|
config.webpack[target] = targetConfig.customize(targetConfig, webpack);
|
|
187
216
|
delete config.webpack[target].customize;
|
|
188
217
|
}
|
package/lib/init-jade-config.js
CHANGED
|
@@ -7,12 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
|
-
const _ = require('lodash');
|
|
11
10
|
const fs = require('fs');
|
|
12
11
|
const prettyjson = require('prettyjson');
|
|
13
12
|
const mergeConfigs = require('./merge-configs');
|
|
14
13
|
const configureWebpack = require('./configure-webpack');
|
|
15
|
-
const configureSass = require('./configure-sass');
|
|
16
14
|
const configurePostCSS = require('./configure-postcss');
|
|
17
15
|
|
|
18
16
|
module.exports = function initJadeConfig(grunt, jadePath, jadeChildPath, jadeChildPaths) {
|
|
@@ -31,7 +29,7 @@ module.exports = function initJadeConfig(grunt, jadePath, jadeChildPath, jadeChi
|
|
|
31
29
|
baseConfig = mergeConfigs(baseConfig, jadePath);
|
|
32
30
|
|
|
33
31
|
// Loop through all detected engine gem paths and merge their Grunt configurations into baseConfig
|
|
34
|
-
for (const childPath of
|
|
32
|
+
for (const childPath of Object.values(jadeChildPaths)) {
|
|
35
33
|
baseConfig = mergeConfigs(baseConfig, childPath);
|
|
36
34
|
}
|
|
37
35
|
|
|
@@ -41,9 +39,6 @@ module.exports = function initJadeConfig(grunt, jadePath, jadeChildPath, jadeChi
|
|
|
41
39
|
// Update baseConfig's Webpack settings with ePublishing defaults:
|
|
42
40
|
baseConfig = configureWebpack(grunt, baseConfig);
|
|
43
41
|
|
|
44
|
-
// Add custom functions and settings to the merged Sass config
|
|
45
|
-
baseConfig = configureSass(baseConfig);
|
|
46
|
-
|
|
47
42
|
if (baseConfig.postcss) {
|
|
48
43
|
baseConfig = configurePostCSS(baseConfig, grunt);
|
|
49
44
|
}
|
package/node-upgrade.md
ADDED
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
# Node.js v8 to v16 Server Upgrade Strategy
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This document outlines a phased approach for upgrading Node.js directly from version 8 to version 16 across our server infrastructure, with rollback procedures at each step.
|
|
6
|
+
|
|
7
|
+
## Server Deployment Overview
|
|
8
|
+
|
|
9
|
+
## Staging Servers
|
|
10
|
+
|
|
11
|
+
### rails-stage-app-10.cloud.epub.net
|
|
12
|
+
|
|
13
|
+
- arwarchitect
|
|
14
|
+
- bevindustry
|
|
15
|
+
- bioworld
|
|
16
|
+
- creditunionmagazine
|
|
17
|
+
- foodengineeringmag
|
|
18
|
+
- halldale
|
|
19
|
+
- packagingstrategies
|
|
20
|
+
- remediation-technology
|
|
21
|
+
- roofingsupplypro
|
|
22
|
+
- rtoinsder
|
|
23
|
+
- supplychainquarterly
|
|
24
|
+
|
|
25
|
+
### rails-stage-app-11.cloud.epub.net
|
|
26
|
+
|
|
27
|
+
- adhesivesmag
|
|
28
|
+
- agproud
|
|
29
|
+
- assemblymag
|
|
30
|
+
- cannabisproductsinsider
|
|
31
|
+
- centerwatch
|
|
32
|
+
- dairyfoods
|
|
33
|
+
- dairyprocessing
|
|
34
|
+
- demoepub
|
|
35
|
+
- demoepub_docker_image
|
|
36
|
+
- discoverconcordma
|
|
37
|
+
- esmagazine
|
|
38
|
+
- farm-equipment
|
|
39
|
+
- fdanews
|
|
40
|
+
- thecarlatreport
|
|
41
|
+
- thescxchange
|
|
42
|
+
- wholefoodsmagazine
|
|
43
|
+
|
|
44
|
+
### continuum-stage-app-6.epublishing.internal
|
|
45
|
+
|
|
46
|
+
- agequipmentintelligence
|
|
47
|
+
- alpha
|
|
48
|
+
- bakemag
|
|
49
|
+
- beverage-digest
|
|
50
|
+
- bnpevents
|
|
51
|
+
- businesswatchnetwork
|
|
52
|
+
- continuum
|
|
53
|
+
- covercropstrategies
|
|
54
|
+
- foodbusinessnews
|
|
55
|
+
- insidemortgagefinance
|
|
56
|
+
- logisticsdevelopmentforum
|
|
57
|
+
- meatpoultry
|
|
58
|
+
- newsletterclarivate
|
|
59
|
+
- petfoodprocessing
|
|
60
|
+
- supermarketperimeter
|
|
61
|
+
- supplychainbrain
|
|
62
|
+
- worldgrain
|
|
63
|
+
|
|
64
|
+
### continuum-stage-app-5.epublishing.internal
|
|
65
|
+
|
|
66
|
+
- agri-pulse
|
|
67
|
+
- architecturalrecord
|
|
68
|
+
- enr
|
|
69
|
+
- graphql_api
|
|
70
|
+
- metaservices
|
|
71
|
+
- qualitymag
|
|
72
|
+
- roofingcontractor
|
|
73
|
+
- safetyandhealthmagazine
|
|
74
|
+
- spokanejournal
|
|
75
|
+
- stoneworld
|
|
76
|
+
- thehabitatgroup
|
|
77
|
+
- thesunmagazine
|
|
78
|
+
|
|
79
|
+
### rails-stage-app-8.cloud.epub.net
|
|
80
|
+
|
|
81
|
+
- achrnews
|
|
82
|
+
- americanfarriers
|
|
83
|
+
- foodmaster
|
|
84
|
+
- geartechnology
|
|
85
|
+
- ishn
|
|
86
|
+
- pcimag
|
|
87
|
+
- pmengineer
|
|
88
|
+
- pmmag
|
|
89
|
+
- powertransmission
|
|
90
|
+
- precisionfarmingdealer
|
|
91
|
+
- preparedfoods
|
|
92
|
+
- provisioneronline
|
|
93
|
+
- rurallifestyledealer
|
|
94
|
+
- securitymagazine
|
|
95
|
+
- striptillfarmer
|
|
96
|
+
- wconline
|
|
97
|
+
|
|
98
|
+
### rails-stage-app-9.cloud.epub.net
|
|
99
|
+
|
|
100
|
+
- bakingbusiness
|
|
101
|
+
- food-safety
|
|
102
|
+
- missioncriticalmagazine
|
|
103
|
+
- mwjournal
|
|
104
|
+
- phcppros
|
|
105
|
+
- randrmagonline
|
|
106
|
+
- refrigeratedfrozenfood
|
|
107
|
+
- sdmmag
|
|
108
|
+
- signalintegrityjournal
|
|
109
|
+
- snackandbakery
|
|
110
|
+
- supplyht
|
|
111
|
+
- thedriller
|
|
112
|
+
- tricitiesbusinessnews
|
|
113
|
+
|
|
114
|
+
## Production Servers
|
|
115
|
+
|
|
116
|
+
### bnp-app-11.cloud.epub.net
|
|
117
|
+
|
|
118
|
+
- achrnews
|
|
119
|
+
- adhesivesmag
|
|
120
|
+
- arwarchitect
|
|
121
|
+
- bevindustry
|
|
122
|
+
- dairyfoods
|
|
123
|
+
- esmagazine
|
|
124
|
+
- food-safety
|
|
125
|
+
- missioncriticalmagazine
|
|
126
|
+
- pcimag
|
|
127
|
+
- pmengineer
|
|
128
|
+
- thedriller
|
|
129
|
+
|
|
130
|
+
### bnp-app-12.cloud.epub.net
|
|
131
|
+
|
|
132
|
+
- achrnews
|
|
133
|
+
- adhesivesmag
|
|
134
|
+
- arwarchitect
|
|
135
|
+
- bevindustry
|
|
136
|
+
- dairyfoods
|
|
137
|
+
- esmagazine
|
|
138
|
+
- food-safety
|
|
139
|
+
- missioncriticalmagazine
|
|
140
|
+
- pcimag
|
|
141
|
+
- pmengineer
|
|
142
|
+
- thedriller
|
|
143
|
+
|
|
144
|
+
### bnp-app-13.cloud.epub.net
|
|
145
|
+
|
|
146
|
+
- achrnews
|
|
147
|
+
- assemblymag
|
|
148
|
+
- bnpevents
|
|
149
|
+
- cannabisproductsinsider
|
|
150
|
+
- enr
|
|
151
|
+
- foodmaster
|
|
152
|
+
- preparedfoods
|
|
153
|
+
- provisioneronline
|
|
154
|
+
- randrmagonline
|
|
155
|
+
- refrigeratedfrozenfood
|
|
156
|
+
- remediation-technology
|
|
157
|
+
- sdmmag
|
|
158
|
+
- snackandbakery
|
|
159
|
+
- supplyht
|
|
160
|
+
- wconline
|
|
161
|
+
|
|
162
|
+
### bnp-app-14.cloud.epub.net
|
|
163
|
+
|
|
164
|
+
- achrnews
|
|
165
|
+
- assemblymag
|
|
166
|
+
- bnpevents
|
|
167
|
+
- cannabisproductsinsider
|
|
168
|
+
- enr
|
|
169
|
+
- foodmaster
|
|
170
|
+
- preparedfoods
|
|
171
|
+
- provisioneronline
|
|
172
|
+
- randrmagonline
|
|
173
|
+
- refrigeratedfrozenfood
|
|
174
|
+
- remediation-technology
|
|
175
|
+
- sdmmag
|
|
176
|
+
- snackandbakery
|
|
177
|
+
- supplyht
|
|
178
|
+
- wconline
|
|
179
|
+
|
|
180
|
+
### bnp-app-15.cloud.epub.net
|
|
181
|
+
|
|
182
|
+
- achrnews
|
|
183
|
+
- architecturalrecord
|
|
184
|
+
- enr
|
|
185
|
+
- foodengineeringmag
|
|
186
|
+
- ishn
|
|
187
|
+
- logisticsdevelopmentforum
|
|
188
|
+
- packagingstrategies
|
|
189
|
+
- pmmag
|
|
190
|
+
- qualitymag
|
|
191
|
+
- roofingcontractor
|
|
192
|
+
- roofingsupplypro
|
|
193
|
+
- securitymagazine
|
|
194
|
+
- stoneworld
|
|
195
|
+
|
|
196
|
+
### bnp-app-16.cloud.epub.net
|
|
197
|
+
|
|
198
|
+
- achrnews
|
|
199
|
+
- architecturalrecord
|
|
200
|
+
- enr
|
|
201
|
+
- foodengineeringmag
|
|
202
|
+
- ishn
|
|
203
|
+
- logisticsdevelopmentforum
|
|
204
|
+
- packagingstrategies
|
|
205
|
+
- pmmag
|
|
206
|
+
- qualitymag
|
|
207
|
+
- roofingcontractor
|
|
208
|
+
- roofingsupplypro
|
|
209
|
+
- securitymagazine
|
|
210
|
+
- stoneworld
|
|
211
|
+
|
|
212
|
+
### rails-app-101.cloud.epub.net
|
|
213
|
+
|
|
214
|
+
- agequipmentintelligence
|
|
215
|
+
- agri-pulse
|
|
216
|
+
- americanfarriers
|
|
217
|
+
- discoverconcordma
|
|
218
|
+
- phcppros
|
|
219
|
+
- thecarlatreport
|
|
220
|
+
- thehabitatgroup
|
|
221
|
+
- wholefoodsmagazine
|
|
222
|
+
|
|
223
|
+
### rails-app-102.cloud.epub.net
|
|
224
|
+
|
|
225
|
+
- agequipmentintelligence
|
|
226
|
+
- agri-pulse
|
|
227
|
+
- americanfarriers
|
|
228
|
+
- discoverconcordma
|
|
229
|
+
- phcppros
|
|
230
|
+
- thecarlatreport
|
|
231
|
+
- thehabitatgroup
|
|
232
|
+
- wholefoodsmagazine
|
|
233
|
+
|
|
234
|
+
### rails-app-103.cloud.epub.net
|
|
235
|
+
|
|
236
|
+
- beverage-digest
|
|
237
|
+
- centerwatch
|
|
238
|
+
- covercropstrategies
|
|
239
|
+
- farm-equipment
|
|
240
|
+
- fdanews
|
|
241
|
+
- halldale
|
|
242
|
+
- newsletterclarivate
|
|
243
|
+
- rtoinsder
|
|
244
|
+
- rurallifestyledealer
|
|
245
|
+
- signalintegrityjournal
|
|
246
|
+
|
|
247
|
+
### rails-app-104.cloud.epub.net
|
|
248
|
+
|
|
249
|
+
- beverage-digest
|
|
250
|
+
- centerwatch
|
|
251
|
+
- covercropstrategies
|
|
252
|
+
- farm-equipment
|
|
253
|
+
- fdanews
|
|
254
|
+
- halldale
|
|
255
|
+
- newsletterclarivate
|
|
256
|
+
- rtoinsder
|
|
257
|
+
- rurallifestyledealer
|
|
258
|
+
- signalintegrityjournal
|
|
259
|
+
|
|
260
|
+
### rails-app-105.cloud.epub.net
|
|
261
|
+
|
|
262
|
+
- foodbusinessnews
|
|
263
|
+
- hfmmagazine
|
|
264
|
+
- mwjournal
|
|
265
|
+
- no-tillfarmer
|
|
266
|
+
- precisionfarmingdealer
|
|
267
|
+
- safetyandhealthmagazine
|
|
268
|
+
- striptillfarmer
|
|
269
|
+
- supplychainbrain
|
|
270
|
+
- supplychainquarterly
|
|
271
|
+
- thescxchange
|
|
272
|
+
|
|
273
|
+
### rails-app-106.cloud.epub.net
|
|
274
|
+
|
|
275
|
+
- foodbusinessnews
|
|
276
|
+
- hfmmagazine
|
|
277
|
+
- mwjournal
|
|
278
|
+
- no-tillfarmer
|
|
279
|
+
- precisionfarmingdealer
|
|
280
|
+
- safetyandhealthmagazine
|
|
281
|
+
- striptillfarmer
|
|
282
|
+
- supplychainbrain
|
|
283
|
+
- supplychainquarterly
|
|
284
|
+
- thescxchange
|
|
285
|
+
|
|
286
|
+
### rails-app-107.cloud.epub.net
|
|
287
|
+
|
|
288
|
+
- agproud
|
|
289
|
+
- bakingbusiness
|
|
290
|
+
- bioworld
|
|
291
|
+
- geartechnology
|
|
292
|
+
- powertransmission
|
|
293
|
+
- spokanejournal
|
|
294
|
+
- thesunmagazine
|
|
295
|
+
- tricitiesbusinessnews
|
|
296
|
+
|
|
297
|
+
### rails-app-108.cloud.epub.net
|
|
298
|
+
|
|
299
|
+
- agproud
|
|
300
|
+
- bakingbusiness
|
|
301
|
+
- bioworld
|
|
302
|
+
- geartechnology
|
|
303
|
+
- powertransmission
|
|
304
|
+
- spokanejournal
|
|
305
|
+
- thesunmagazine
|
|
306
|
+
- tricitiesbusinessnews
|
|
307
|
+
|
|
308
|
+
### rails-internal-app-101.cloud.epub.net
|
|
309
|
+
|
|
310
|
+
- metaservices
|
|
311
|
+
|
|
312
|
+
### rails-internal-app-102.cloud.epub.net
|
|
313
|
+
|
|
314
|
+
- metaservices
|
|
315
|
+
|
|
316
|
+
## Pre-Upgrade Preparation
|
|
317
|
+
|
|
318
|
+
1. Create full system backups of all servers
|
|
319
|
+
2. Update package.json dependencies for v16 compatibility on all repositories in the rails/upgrade/master branch. This is already done for all jade sites.
|
|
320
|
+
|
|
321
|
+
## Phase 1: Staging Environment Upgrade (v8 → v16)
|
|
322
|
+
|
|
323
|
+
1. Upgrade all staging servers to Node.js 16
|
|
324
|
+
2. Merge all jade sites' rails/upgrade/master branch into their respective repositories' staging branch.
|
|
325
|
+
3. Update package.json dependencies for v16 compatibility (already done for all jade sites)
|
|
326
|
+
4. Deploy staging branch to all staging servers
|
|
327
|
+
5. Run test suite and fix any breaking changes
|
|
328
|
+
|
|
329
|
+
### Rollback Plan Phase 1
|
|
330
|
+
|
|
331
|
+
- Restore system backup
|
|
332
|
+
- Revert staging branch to previous state
|
|
333
|
+
- Reinstall Node.js v8
|
|
334
|
+
- Verify system functionality
|
|
335
|
+
|
|
336
|
+
**By upgrading staging servers first, we can thoroughly verify each site's functionality in a controlled environment without any impact to production traffic.** This critical staging phase significantly reduces downtime risks and provides a crucial safety net, allowing us to identify and resolve any compatibility issues before touching customer-facing systems. This approach is essential for maintaining system reliability throughout the upgrade process.
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
## Phase 2: Production Environment Upgrade (v8 → v16)
|
|
340
|
+
|
|
341
|
+
1. Select one production server for initial upgrade
|
|
342
|
+
2. Upgrade selected server to Node.js 16
|
|
343
|
+
3. Merge rails/upgrade/master branch into that server's repository's master branch
|
|
344
|
+
4. Deploy master branch to selected server for all sites on that server
|
|
345
|
+
5. Monitor performance metrics and error rates for 24 hours
|
|
346
|
+
6. If stable, continue monitoring for 1 week
|
|
347
|
+
7. Repeat steps 1-6 for each remaining production server
|
|
348
|
+
|
|
349
|
+
### Rollback Plan Phase 2
|
|
350
|
+
|
|
351
|
+
- Restore system backup
|
|
352
|
+
- Revert master branch to previous state
|
|
353
|
+
- Reinstall Node.js v8
|
|
354
|
+
- Verify system functionality
|
|
355
|
+
|
|
356
|
+
## Success Criteria
|
|
357
|
+
|
|
358
|
+
- Zero downtime during transitions
|
|
359
|
+
- Error rates remain at or below baseline
|
|
360
|
+
- Response times within 10% of baseline
|
|
361
|
+
- All automated tests passing
|
|
362
|
+
- No customer-reported issues
|
|
363
|
+
|
|
364
|
+
## Timeline
|
|
365
|
+
|
|
366
|
+
- Phase 1: 2 weeks
|
|
367
|
+
- Phase 2: 3 weeks
|
|
368
|
+
- Total: 5 weeks
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epublishing/grunt-epublishing",
|
|
3
3
|
"description": "Automated front-end tasks for ePublishing Jade and client sites.",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.2",
|
|
5
5
|
"homepage": "https://www.epublishing.com",
|
|
6
6
|
"contributors": [
|
|
7
7
|
{
|
|
@@ -11,22 +11,32 @@
|
|
|
11
11
|
{
|
|
12
12
|
"name": "Mike Green",
|
|
13
13
|
"email": "mgreen@epublishing.com"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "Michael Hedges",
|
|
17
|
+
"email": "mhedges@epublishing.com"
|
|
14
18
|
}
|
|
15
19
|
],
|
|
16
20
|
"repository": "bitbucket:epub_dev/grunt-epublishing",
|
|
17
21
|
"license": "MIT",
|
|
18
22
|
"engines": {
|
|
19
|
-
"node": ">=
|
|
23
|
+
"node": ">= 16.20.2"
|
|
20
24
|
},
|
|
21
25
|
"dependencies": {
|
|
22
|
-
"@
|
|
26
|
+
"@babel/core": "^7.25.2",
|
|
27
|
+
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
28
|
+
"@babel/plugin-transform-react-jsx": "^7.25.2",
|
|
29
|
+
"@babel/preset-env": "^7.25.4",
|
|
30
|
+
"@babel/preset-react": "^7.24.7",
|
|
31
|
+
"@epublishing/babel-preset-epublishing": "^0.2.0",
|
|
23
32
|
"@epublishing/get-gem-paths": "^0.1.1",
|
|
24
33
|
"@epublishing/grunt-install-eslint": "^0.1.1",
|
|
25
34
|
"@epublishing/jade-resolver": "^0.1.2",
|
|
26
35
|
"async": "^2.6.1",
|
|
27
|
-
"babel-loader": "^
|
|
36
|
+
"babel-loader": "^9.1.3",
|
|
28
37
|
"babel-minify-webpack-plugin": "^0.3.0",
|
|
29
|
-
"
|
|
38
|
+
"babel-plugin-transform-react-jsx": "^6.24.1",
|
|
39
|
+
"bourbon": "^7.3.0",
|
|
30
40
|
"breakpoint-sass": "^2.7.0",
|
|
31
41
|
"chalk": "^2.4.1",
|
|
32
42
|
"cli-spinner": "^0.2.8",
|
|
@@ -37,7 +47,7 @@
|
|
|
37
47
|
"cssnano": "^4.0.5",
|
|
38
48
|
"es5-shim": "^4.5.10",
|
|
39
49
|
"es6-promise": "^4.2.4",
|
|
40
|
-
"eslint": "^
|
|
50
|
+
"eslint": "^4.2.0",
|
|
41
51
|
"eslint-friendly-formatter": "^4.0.1",
|
|
42
52
|
"eslint-loader": "^2.1.0",
|
|
43
53
|
"eslint-plugin-import": "^2.13.0",
|
|
@@ -56,7 +66,6 @@
|
|
|
56
66
|
"grunt-contrib-uglify": "^3.4.0",
|
|
57
67
|
"grunt-contrib-watch": "^1.1.0",
|
|
58
68
|
"grunt-postcss": "^0.9.0",
|
|
59
|
-
"grunt-sass": "^2.1.0",
|
|
60
69
|
"grunt-webpack": "^3.1.2",
|
|
61
70
|
"handlebars": "^4.0.11",
|
|
62
71
|
"handlebars-loader": "^1.6.0",
|
|
@@ -64,10 +73,10 @@
|
|
|
64
73
|
"jit-grunt": "^0.10.0",
|
|
65
74
|
"listr": "^0.14.1",
|
|
66
75
|
"lodash": "^4.17.10",
|
|
67
|
-
"node-sass": "4.7.2",
|
|
68
76
|
"postcss-css-variables": "^0.9.0",
|
|
69
77
|
"prettyjson": "^1.2.1",
|
|
70
78
|
"read-pkg": "^4.0.1",
|
|
79
|
+
"sass": "^1.71.1",
|
|
71
80
|
"style-loader": "^0.20.2",
|
|
72
81
|
"susy": "^2.2.14",
|
|
73
82
|
"time-grunt": "^1.4.0",
|
package/tasks/jade.js
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
|
|
3
|
+
if (typeof globalThis === 'undefined') {
|
|
4
|
+
(function() {
|
|
5
|
+
if (typeof self !== 'undefined') { self.globalThis = self; }
|
|
6
|
+
else if (typeof window !== 'undefined') { window.globalThis = window; }
|
|
7
|
+
else if (typeof global !== 'undefined') { global.globalThis = global; }
|
|
8
|
+
else {
|
|
9
|
+
Object.defineProperty(Object.prototype, 'globalThis', {
|
|
10
|
+
get: function() {
|
|
11
|
+
return this;
|
|
12
|
+
},
|
|
13
|
+
configurable: true
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
})();
|
|
17
|
+
}
|
|
18
|
+
|
|
3
19
|
'use strict';
|
|
4
20
|
|
|
5
21
|
const path = require('path');
|
package/tasks/npm-install.js
CHANGED
package/tasks/sass.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const sass = require('sass');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs').promises;
|
|
5
|
+
|
|
6
|
+
module.exports = grunt => {
|
|
7
|
+
grunt.registerMultiTask('sass', 'Compile Sass to CSS', function () {
|
|
8
|
+
const done = this.async();
|
|
9
|
+
const options = this.options({
|
|
10
|
+
precision: 10,
|
|
11
|
+
sourceMap: false,
|
|
12
|
+
quiet: true,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
(async () => {
|
|
16
|
+
await Promise.all(this.files.map(async item => {
|
|
17
|
+
const [src] = item.src;
|
|
18
|
+
|
|
19
|
+
if (!src || path.basename(src)[0] === '_') {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const result = sass.compile(src, {
|
|
25
|
+
...options,
|
|
26
|
+
style: options.style || 'expanded'
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
await fs.writeFile(item.dest, result.css);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
grunt.fatal(error.formatted || error.message || error);
|
|
32
|
+
}
|
|
33
|
+
}));
|
|
34
|
+
})().catch(error => {
|
|
35
|
+
grunt.fatal(error.formatted || error.message || error);
|
|
36
|
+
}).then(done);
|
|
37
|
+
});
|
|
38
|
+
};
|
package/lib/configure-sass.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This function merges custom SassScript functions into the base Sass config
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
'use strict';
|
|
6
|
-
|
|
7
|
-
const _ = require('lodash');
|
|
8
|
-
const sass = require('node-sass');
|
|
9
|
-
const NODE_ENV = process.env.NODE_ENV || 'development';
|
|
10
|
-
|
|
11
|
-
module.exports = function configureSass(config) {
|
|
12
|
-
|
|
13
|
-
config.sass.options.functions = {
|
|
14
|
-
'epub-show-deprecation-warnings()': () => {
|
|
15
|
-
if (_.includes([ 'local', 'development' ], NODE_ENV)) {
|
|
16
|
-
return sass.types.Boolean.TRUE;
|
|
17
|
-
}
|
|
18
|
-
return sass.types.Boolean.FALSE;
|
|
19
|
-
},
|
|
20
|
-
'epub-node-env()': () => new sass.types.String(NODE_ENV),
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
return config;
|
|
24
|
-
};
|