UNPKG

7.38 kBJavaScriptView Raw
1//-------------------------------------
2//-- Scripts
3//-------------------------------------
4'use strict';
5
6// const debug = require('gulp-debug');
7const { exec } = require('child_process');
8const corejs = require('core-js-builder');
9const gulp = require('gulp');
10const cache = require('gulp-cached');
11const eslint = require('gulp-eslint');
12const gulpif = require('gulp-if');
13const lec = require('gulp-line-ending-corrector');
14const uglify = require('gulp-uglify');
15const cloneDeep = require('lodash.clonedeep');
16const modernizr = require('modernizr');
17const pluralize = require('pluralize');
18const fsp = require('@absolunet/fsp');
19const fss = require('@absolunet/fss');
20const include = require('@absolunet/gulp-include');
21const { terminal } = require('@absolunet/terminal');
22const env = require('~/helpers/env');
23const flow = require('~/helpers/flow');
24const paths = require('~/helpers/paths');
25const toolbox = require('~/helpers/toolbox');
26const util = require('~/helpers/util');
27
28
29module.exports = () => {
30
31 //-- Lint JS
32 flow.createTask('scripts-lint', ({ taskName }) => {
33 return gulp.src(paths.files.scriptsLint)
34 // .pipe(toolbox.plumber()) // skip cuz of watch
35
36 .pipe(cache('scripts', { optimizeMemory: true }))
37
38 .pipe(gulpif(env.isWindows, lec()))
39
40 .pipe(eslint())
41
42 .pipe(eslint.results((files) => {
43 let hasErrors = false;
44
45 files.forEach((file) => {
46 if (file.errorCount || file.warningCount) {
47 delete cache.caches.scripts[file.filePath];
48 hasErrors = true;
49 }
50 });
51
52 if (!hasErrors) {
53 toolbox.log(taskName, `${pluralize('file', files.length, true)} linted`);
54 }
55 }))
56
57 .pipe(eslint.format('stylish'))
58
59 .pipe(eslint.failAfterError())
60 ;
61 });
62
63
64 //-- Convert constants to JS
65 flow.createTask('scripts-constants', ({ taskName }) => {
66 const streams = [];
67
68 for (const name of Object.keys(env.bundles)) {
69 const data = {
70 [env.id]: env.workflowConfig.version,
71 project: env.packageConfig.name,
72 bundle: name,
73 konstan: util.parseKonstan('scripts', name, env.bundles[name].output)
74 };
75
76 /* eslint-disable function-paren-newline */
77 streams.push(
78 toolbox.vinylStream(paths.filename.konstanScripts, `var konstan = ${JSON.stringify(data, null, '\t')};`)
79 .pipe(toolbox.plumber())
80 .pipe(gulp.dest(`${paths.directory.cacheScripts}/${name}`))
81 );
82 /* eslint-enable function-paren-newline */
83 }
84
85 return toolbox.mergeStreams(streams).on('finish', () => {
86 flow.skipOnWatch(taskName);
87 toolbox.log(taskName, `${pluralize('file', streams.length, true)} generated`);
88 });
89
90 });
91
92
93 //-- Generate vendor libraries
94 flow.createTask('scripts-vendors', ({ taskName }) => {
95
96 const log = (name, file) => {
97 toolbox.log(taskName, `${name} built`, toolbox.filesize(file));
98 };
99
100 return toolbox.fakeStream((callback) => {
101
102 const modernizrBuild = new Promise((resolve) => {
103 modernizr.build(fss.readYaml(paths.config.modernizr), (result) => {
104 const file = `${paths.directory.cacheScripts}/${paths.filename.modernizr}.${paths.extension.scripts}`;
105 fsp.ensureFile(file).then(() => {
106 fss.writeFile(file, result);
107 log('Modernizr', file);
108 resolve();
109 });
110 });
111 });
112
113 const lodashBuild = new Promise((resolve) => {
114 const options = util.parseLodash();
115 const file = `${paths.directory.cacheScripts}/${paths.filename.lodash}.${paths.extension.scripts}`;
116
117 exec(`node ${paths.config.lodashBin} ${options} --development --output ${file}`, (error, stdout, stderr) => {
118 if (error !== null) {
119 terminal.error(stderr);
120 }
121 log('Lodash', file);
122 resolve();
123 });
124 });
125
126 const polyfillBuild = new Promise((resolve) => {
127 const file = `${paths.directory.cacheScripts}/${paths.filename.polyfill}.${paths.extension.scripts}`;
128
129 corejs({
130 modules: ['web', 'es'],
131 targets: env.configRaw.polyfill,
132 filename: file
133 }).then(() => {
134 fsp.appendFile(file, fss.readFile(paths.config.regeneratorRuntime, 'utf8')).then(() => {
135 log('core-js polyfill', file);
136 resolve();
137 });
138 });
139 });
140
141
142 Promise.all([modernizrBuild, lodashBuild, polyfillBuild]).then(() => {
143 flow.skipOnWatch(taskName);
144 callback();
145 });
146
147 });
148
149 });
150
151
152 //-- Compile
153 flow.createTask('scripts-compile', ({ taskName }) => {
154 const streams = [];
155
156 for (const name of Object.keys(env.bundles)) {
157 const bundle = env.bundles[name];
158
159 // Babel extra allowed
160 const babelExtraAllowed = util.getBabelAllowedRules(bundle.scripts.allowBabel);
161
162 // For each collection
163 for (const collection of Object.keys(bundle.scripts.collections)) {
164 const list = cloneDeep(bundle.scripts.collections[collection]);
165
166 // Resolve real filepaths
167 const replacements = {
168 konstan: `${paths.folder.cacheScripts}/${name}/${paths.filename.konstan}`,
169 lodash: `${paths.folder.cacheScripts}/${paths.filename.lodash}`,
170 modernizr: `${paths.folder.cacheScripts}/${paths.filename.modernizr}`,
171 polyfill: `${paths.folder.cacheScripts}/${paths.filename.polyfill}`
172 };
173 for (const title of Object.keys(replacements)) {
174 const pos = list.indexOf(`~${title}`);
175 if (pos !== -1) {
176 list[pos] = replacements[title];
177 }
178 }
179
180 // Require each file
181 list.forEach((file, i) => {
182 list[i] = `//= require ${file}`;
183 });
184
185 const toMinify = (bundle.scripts.options.minify && !env.watching) || env.production;
186 const filename = `${collection}.${paths.extension.scripts}`;
187 const destination = `${bundle.output.build}/${paths.build.scripts}`;
188 const source = `${util.getGeneratedBanner(name)} (function(global, undefined) { \n\t${list.join('\n')}\n })(typeof window !== 'undefined' ? window : this);\n`;
189
190 /* eslint-disable function-paren-newline */
191 streams.push(
192 toolbox.vinylStream(filename, source)
193 .pipe(toolbox.plumber())
194
195 .pipe(include({
196 basePath: paths.directory.root,
197 autoExtension: true,
198 partialPrefix: true,
199 fileProcess: (options) => {
200 return util.babelProcess(options, bundle.scripts.options.babel, babelExtraAllowed);
201 }
202 }))
203
204 .pipe(gulpif(toMinify, uglify({ output: { comments: 'some' } })))
205
206 .pipe(gulp.dest(`${paths.directory.root}/${destination}`))
207
208 .on('finish', () => {
209 toolbox.log(taskName, `'${destination}/${filename}' written`, toolbox.filesize(`${paths.directory.root}/${destination}/${filename}`));
210 })
211 );
212 /* eslint-enable function-paren-newline */
213 }
214 }
215
216 return toolbox.mergeStreams(streams);
217
218 }, gulp.parallel('scripts-lint', 'scripts-constants', 'scripts-vendors'));
219
220
221
222
223
224
225 //-- Rebuild
226 flow.createSequence('scripts', gulp.series('scripts-compile'), {
227 cleanBundle: ({ name, bundle }) => {
228 const buildPath = `${paths.directory.root}/${bundle.output.build}/${paths.build.scripts}`;
229 const cachePath = `${paths.directory.cacheScripts}/${name}`;
230
231 if (env.isScopeSubbundle) {
232 return Object.keys(bundle.scripts.collections).map((collection) => {
233 return [
234 `${buildPath}/${collection}.${paths.extension.scripts}`,
235 `${cachePath}/${collection}.${paths.extension.scripts}`
236 ];
237 }).flat();
238 }
239
240 return [buildPath, cachePath];
241 }
242 });
243
244};