@epublishing/grunt-epublishing 0.3.19 → 0.3.23
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 +2 -2
- package/lib/init-jade-config.js +0 -5
- package/package.json +1 -3
- package/tasks/sass.js +131 -16
package/lib/configure-webpack.js
CHANGED
|
@@ -53,7 +53,7 @@ module.exports = function configureWebpack(grunt, config) {
|
|
|
53
53
|
if (!config.babelLoader) {
|
|
54
54
|
config.babelLoader = {
|
|
55
55
|
exceptions: [],
|
|
56
|
-
exclude: /(node_modules
|
|
56
|
+
exclude: /(node_modules)/,
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -144,7 +144,7 @@ module.exports = function configureWebpack(grunt, config) {
|
|
|
144
144
|
rules.push({
|
|
145
145
|
enforce: "pre",
|
|
146
146
|
test: /\.js$/,
|
|
147
|
-
exclude: /(node_modules|
|
|
147
|
+
exclude: /(node_modules|public|vendor)/,
|
|
148
148
|
loader: "eslint-loader",
|
|
149
149
|
options: {
|
|
150
150
|
configFile: eslintConfig,
|
package/lib/init-jade-config.js
CHANGED
|
@@ -69,11 +69,6 @@ module.exports = function initJadeConfig(grunt, jadePath, jadeChildPath, jadeChi
|
|
|
69
69
|
// Add package.json to the grunt config
|
|
70
70
|
grunt.config.set('pkg', grunt.file.readJSON('package.json'));
|
|
71
71
|
|
|
72
|
-
// Check to see if we need to add the bower tasks
|
|
73
|
-
if (fs.existsSync('bower.json')) {
|
|
74
|
-
jadeTasks.unshift('bower-install-simple', 'bower');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
72
|
// Register the main jade task!
|
|
78
73
|
grunt.registerTask('jade', jadeTasks);
|
|
79
74
|
|
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.3.
|
|
4
|
+
"version": "0.3.23",
|
|
5
5
|
"homepage": "https://www.epublishing.com",
|
|
6
6
|
"contributors": [
|
|
7
7
|
{
|
|
@@ -54,8 +54,6 @@
|
|
|
54
54
|
"grunt": "^1.0.3",
|
|
55
55
|
"grunt-babel": "^7.0.0",
|
|
56
56
|
"grunt-bless": "^1.0.2",
|
|
57
|
-
"grunt-bower": "^0.21.4",
|
|
58
|
-
"grunt-bower-install-simple": "^1.2.6",
|
|
59
57
|
"grunt-contrib-clean": "^1.1.0",
|
|
60
58
|
"grunt-contrib-concat": "^1.0.1",
|
|
61
59
|
"grunt-contrib-uglify": "^3.4.0",
|
package/tasks/sass.js
CHANGED
|
@@ -2,37 +2,152 @@
|
|
|
2
2
|
const util = require('util');
|
|
3
3
|
const sass = require('sass');
|
|
4
4
|
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const fsPromises = require('fs').promises;
|
|
7
|
+
const crypto = require('crypto');
|
|
5
8
|
|
|
6
9
|
module.exports = grunt => {
|
|
7
|
-
|
|
10
|
+
// Cache for compiled results
|
|
11
|
+
const cache = new Map();
|
|
12
|
+
|
|
13
|
+
// Generate cache key for a file
|
|
14
|
+
const getCacheKey = (filePath, options) => {
|
|
15
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
16
|
+
const optionsHash = crypto.createHash('md5').update(JSON.stringify(options)).digest('hex');
|
|
17
|
+
const contentHash = crypto.createHash('md5').update(content).digest('hex');
|
|
18
|
+
return `${filePath}:${contentHash}:${optionsHash}`;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Check if file needs recompilation
|
|
22
|
+
const needsRecompilation = async (src, dest, options) => {
|
|
23
|
+
try {
|
|
24
|
+
const cacheKey = getCacheKey(src, options);
|
|
25
|
+
const cached = cache.get(cacheKey);
|
|
26
|
+
|
|
27
|
+
if (!cached) return true;
|
|
28
|
+
|
|
29
|
+
// Check if destination file exists and is newer than source
|
|
30
|
+
const srcStats = await fsPromises.stat(src);
|
|
31
|
+
const destStats = await fsPromises.stat(dest);
|
|
32
|
+
|
|
33
|
+
return srcStats.mtime > destStats.mtime;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
// If destination doesn't exist or other error, recompile
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
grunt.registerMultiTask('sass', 'Compile Sass to CSS with performance optimizations', function () {
|
|
8
41
|
const done = this.async();
|
|
42
|
+
const startTime = Date.now();
|
|
9
43
|
|
|
10
44
|
const options = this.options({
|
|
11
|
-
precision: 10
|
|
45
|
+
precision: 10,
|
|
46
|
+
cache: true,
|
|
47
|
+
parallel: true,
|
|
48
|
+
maxConcurrency: require('os').cpus().length
|
|
12
49
|
});
|
|
13
50
|
|
|
14
|
-
|
|
15
|
-
|
|
51
|
+
// Filter out partial files and create compilation tasks
|
|
52
|
+
const compilationTasks = this.files
|
|
53
|
+
.map(item => {
|
|
16
54
|
const [src] = item.src;
|
|
17
|
-
|
|
18
55
|
if (!src || path.basename(src)[0] === '_') {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return { src, dest: item.dest, options };
|
|
59
|
+
})
|
|
60
|
+
.filter(Boolean);
|
|
61
|
+
|
|
62
|
+
if (compilationTasks.length === 0) {
|
|
63
|
+
grunt.log.writeln('No Sass files to compile');
|
|
64
|
+
done();
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Process files with concurrency control
|
|
69
|
+
const processFile = async (task) => {
|
|
70
|
+
const { src, dest, options: taskOptions } = task;
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
// Check if recompilation is needed
|
|
74
|
+
if (options.cache && !(await needsRecompilation(src, dest, taskOptions))) {
|
|
75
|
+
grunt.log.debug(`Skipping ${src} (cached)`);
|
|
19
76
|
return;
|
|
20
77
|
}
|
|
21
78
|
|
|
22
|
-
|
|
79
|
+
// Compile Sass
|
|
80
|
+
const sassOptions = {
|
|
81
|
+
...taskOptions,
|
|
23
82
|
file: src,
|
|
24
|
-
outFile:
|
|
25
|
-
}
|
|
83
|
+
outFile: dest,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const result = await util.promisify(sass.render)(sassOptions);
|
|
87
|
+
|
|
88
|
+
// Write CSS file
|
|
89
|
+
await fsPromises.writeFile(dest, result.css);
|
|
90
|
+
|
|
91
|
+
// Write source map if requested
|
|
92
|
+
if (taskOptions.sourceMap) {
|
|
93
|
+
const mapPath = taskOptions.sourceMap === true ? `${dest}.map` : taskOptions.sourceMap;
|
|
94
|
+
await fsPromises.writeFile(mapPath, result.map);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Cache the result
|
|
98
|
+
if (options.cache) {
|
|
99
|
+
const cacheKey = getCacheKey(src, taskOptions);
|
|
100
|
+
cache.set(cacheKey, {
|
|
101
|
+
css: result.css,
|
|
102
|
+
map: result.map,
|
|
103
|
+
timestamp: Date.now()
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
grunt.log.ok(`Compiled ${src} → ${dest}`);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
grunt.log.error(`Error compiling ${src}: ${error.message}`);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
26
113
|
|
|
27
|
-
|
|
114
|
+
// Process files with controlled concurrency
|
|
115
|
+
const processWithConcurrency = async (tasks, maxConcurrency) => {
|
|
116
|
+
const results = [];
|
|
117
|
+
const chunks = [];
|
|
118
|
+
|
|
119
|
+
// Split tasks into chunks
|
|
120
|
+
for (let i = 0; i < tasks.length; i += maxConcurrency) {
|
|
121
|
+
chunks.push(tasks.slice(i, i + maxConcurrency));
|
|
122
|
+
}
|
|
28
123
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
124
|
+
// Process chunks sequentially, but files within each chunk in parallel
|
|
125
|
+
for (const chunk of chunks) {
|
|
126
|
+
const chunkResults = await Promise.all(chunk.map(processFile));
|
|
127
|
+
results.push(...chunkResults);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return results;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Main execution
|
|
134
|
+
(async () => {
|
|
135
|
+
try {
|
|
136
|
+
if (options.parallel) {
|
|
137
|
+
await processWithConcurrency(compilationTasks, options.maxConcurrency);
|
|
138
|
+
} else {
|
|
139
|
+
// Sequential processing for debugging or when parallel is disabled
|
|
140
|
+
for (const task of compilationTasks) {
|
|
141
|
+
await processFile(task);
|
|
142
|
+
}
|
|
32
143
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
144
|
+
|
|
145
|
+
const duration = Date.now() - startTime;
|
|
146
|
+
grunt.log.ok(`Sass compilation completed in ${duration}ms`);
|
|
147
|
+
done();
|
|
148
|
+
} catch (error) {
|
|
149
|
+
grunt.fatal(error.formatted || error.message);
|
|
150
|
+
}
|
|
151
|
+
})();
|
|
37
152
|
});
|
|
38
153
|
};
|