@videinfra/static-website-builder 1.17.0 → 2.0.0-beta.1

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.
@@ -1,5 +1,5 @@
1
1
  const gulp = require('gulp');
2
- const memoize = require('nano-memoize');
2
+ const { nanomemoize } = require('nano-memoize');
3
3
 
4
4
  const globs = require('./../../lib/globs-helper');
5
5
  const getPaths = require('./../../lib/get-path');
@@ -11,14 +11,18 @@ const taskBeforeDest = require('../../lib/gulp/task-before-dest');
11
11
  const taskWatch = require('../../lib/gulp/task-watch');
12
12
 
13
13
 
14
- const getGlobPaths = memoize(function () {
14
+ const getWatchGlobPaths = function (forChokidar = false) {
15
15
  const sourcePaths = getPaths.getSourcePaths('static');
16
16
  const ignore = getConfig.getTaskConfig('static', 'ignore');
17
17
 
18
18
  return globs.generate(
19
19
  globs.paths(sourcePaths).allFiles(), // Files to watch
20
20
  globs.paths(sourcePaths).paths(ignore).ignore(), // List of files which to ignore
21
+ forChokidar,
21
22
  );
23
+ };
24
+ const getGlobPaths = nanomemoize(function () {
25
+ return getWatchGlobPaths(false);
22
26
  });
23
27
 
24
28
 
@@ -35,7 +39,7 @@ function static () {
35
39
  }
36
40
 
37
41
  function staticWatch () {
38
- return taskWatch(getGlobPaths(), static);
42
+ return taskWatch(getWatchGlobPaths(true), static);
39
43
  }
40
44
 
41
45
 
@@ -2,7 +2,7 @@ const gulp = require('gulp');
2
2
  const gulpif = require('gulp-if');
3
3
  const postcss = require('gulp-postcss');
4
4
  const sourcemaps = require('gulp-sourcemaps');
5
- const memoize = require('nano-memoize');
5
+ const { nanomemoize } = require('nano-memoize');
6
6
  const cached = require('gulp-cached');
7
7
  const dependents = require('gulp-dependents');
8
8
 
@@ -16,7 +16,7 @@ const taskBeforeDest = require('../../lib/gulp/task-before-dest');
16
16
  const taskWatch = require('../../lib/gulp/task-watch');
17
17
 
18
18
 
19
- const getGlobPaths = memoize(function () {
19
+ const getWatchGlobPaths = function (forChokidar = false) {
20
20
  const sourcePaths = getPaths.getSourcePaths('stylesheets');
21
21
  const extensions = getConfig.getTaskConfig('stylesheets', 'extensions');
22
22
  const ignore = getConfig.getTaskConfig('stylesheets', 'ignore');
@@ -24,18 +24,22 @@ const getGlobPaths = memoize(function () {
24
24
  return globs.generate(
25
25
  globs.paths(sourcePaths).filesWithExtensions(extensions), // Files to watch
26
26
  globs.paths(sourcePaths).paths(ignore).ignore(), // List of files which to ignore
27
+ forChokidar,
27
28
  );
29
+ };
30
+
31
+ const getGlobPaths = nanomemoize(function () {
32
+ return getWatchGlobPaths(false);
28
33
  });
29
34
 
30
35
 
31
- const getEngine = memoize(function () {
36
+ const getEngine = function () {
32
37
  const engine = getConfig.getTaskConfig('stylesheets', 'engine');
33
38
  return engine ? engine() : (() => {});
34
- });
39
+ };
35
40
 
36
41
 
37
42
  function stylesheets () {
38
- // console.log(getConfig.getTaskConfig('stylesheets', 'dependents'));
39
43
  return gulp.src(getGlobPaths())
40
44
  .pipe(taskStart())
41
45
 
@@ -61,7 +65,7 @@ function stylesheets () {
61
65
  }
62
66
 
63
67
  function stylesheetsWatch () {
64
- return taskWatch(getGlobPaths(), stylesheets);
68
+ return taskWatch(getWatchGlobPaths(true), stylesheets);
65
69
  }
66
70
 
67
71
 
@@ -64,10 +64,7 @@ test('Font file fake not copied', () => {
64
64
  test('shared.js file exists', () => {
65
65
  return Promise.all([
66
66
  fsPromises.readFile(path.resolve(publicPath, 'assets/javascripts/shared.js'), {'encoding': 'utf8'}).then((js) => {
67
- expect(js.indexOf('console.log("Shared file loaded")')).not.toBe(-1);
68
- }),
69
- fsPromises.readFile(path.resolve(publicPath, 'assets/javascripts/alt/shared.js'), {'encoding': 'utf8'}).then((js) => {
70
- expect(js.indexOf('console.log("Shared file loaded")')).not.toBe(-1);
67
+ expect(js.indexOf('console.log(`Shared file loaded`)')).not.toBe(-1);
71
68
  }),
72
69
  ]);
73
70
  });
@@ -75,20 +72,28 @@ test('shared.js file exists', () => {
75
72
  test('main.js file exists', () => {
76
73
  return Promise.all([
77
74
  fsPromises.readFile(path.resolve(publicPath, 'assets/javascripts/main.js'), {'encoding': 'utf8'}).then((js) => {
78
- expect(js.indexOf('console.log("Hello from main page!")')).not.toBe(-1);
75
+ expect(js.indexOf('console.log(`Hello from main page!`')).not.toBe(-1);
79
76
  }),
80
77
  fsPromises.readFile(path.resolve(publicPath, 'assets/javascripts/alt/main.js'), {'encoding': 'utf8'}).then((js) => {
81
- expect(js.indexOf('console.log("Hello from main page!")')).not.toBe(-1);
78
+ expect(js.indexOf('console.log(`Hello from main page!`')).not.toBe(-1);
82
79
  }),
83
80
  ]);
84
81
  });
85
82
 
86
83
  test('other.js file exists', () => {
87
84
  return fsPromises.readFile(path.resolve(publicPath, 'assets/javascripts/other.js'), {'encoding': 'utf8'}).then((js) => {
88
- expect(js.indexOf('console.log("Hello from other page!")')).not.toBe(-1);
85
+ expect(js.indexOf('console.log(`Hello from other page!`)')).not.toBe(-1);
89
86
  });
90
87
  });
91
88
 
89
+ test('something.ts was converted', () => {
90
+ return Promise.all([
91
+ fsPromises.readFile(path.resolve(publicPath, 'assets/javascripts/something.js'), {'encoding': 'utf8'}).then((js) => {
92
+ expect(js.indexOf('console.log({name:`something`})')).not.toBe(-1);
93
+ }),
94
+ ]);
95
+ });
96
+
92
97
  test('alt/other.js file doesn\'t exist', async () => {
93
98
  expect(fsPromises.stat(path.resolve(publicPath, 'assets/javascripts/alt/other.js'))).rejects.toThrow();
94
99
  });
@@ -96,12 +101,12 @@ test('alt/other.js file doesn\'t exist', async () => {
96
101
  test('.env and .env.local files loaded', () => {
97
102
  return Promise.all([
98
103
  fsPromises.readFile(path.resolve(publicPath, 'assets/javascripts/main.js'), {'encoding': 'utf8'}).then((js) => {
99
- expect(js.indexOf('console.log("env.host ==","https://test-local.tld")')).not.toBe(-1);
100
- expect(js.indexOf('console.log("env.foo ==","foo-global")')).not.toBe(-1);
101
- expect(js.indexOf('console.log("env.bar ==","bar-local")')).not.toBe(-1);
102
- expect(js.indexOf('console.log("env.typeBoolTrue ==",!0)')).not.toBe(-1);
103
- expect(js.indexOf('console.log("env.typeBoolFalse ==",!1)')).not.toBe(-1);
104
- expect(js.indexOf('console.log("env.typeNumber ==",123.456)')).not.toBe(-1);
104
+ expect(js.indexOf('console.log(`env.host ==`,`https://test-local.tld`)')).not.toBe(-1);
105
+ expect(js.indexOf('console.log(`env.foo ==`,`foo-global`)')).not.toBe(-1);
106
+ expect(js.indexOf('console.log(`env.bar ==`,`bar-local`)')).not.toBe(-1);
107
+ expect(js.indexOf('console.log(`env.typeBoolTrue ==`,!0)')).not.toBe(-1);
108
+ expect(js.indexOf('console.log(`env.typeBoolFalse ==`,!1)')).not.toBe(-1);
109
+ expect(js.indexOf('console.log(`env.typeNumber ==`,123.456)')).not.toBe(-1);
105
110
  }),
106
111
  fsPromises.readFile(path.resolve(publicPath, 'env.html'), {'encoding': 'utf8'}).then((html) => {
107
112
  expect(html.indexOf('<p>HOST: https://test-local.tld</p>')).not.toBe(-1);
@@ -0,0 +1,184 @@
1
+ const Transform = require('stream').Transform
2
+ const PluginError = require('plugin-error')
3
+
4
+ const PLUGIN_NAME = 'gulp-starter-rolldown'
5
+ const rolldown = require('rolldown');
6
+ const browserSync = require('browser-sync');
7
+
8
+ /**
9
+ * Evaluate entry file
10
+ *
11
+ * @param {string} code Entry file code
12
+ * @returns {object} Entry file object
13
+ */
14
+ function evalEntry(code) {
15
+ const fullCode = `let _return = {};
16
+ ${code.replace(/\bexport\b[\s\t\r\n]*([^\s\t]+)/g, '_return.$1 =')}
17
+ return _return;`;
18
+
19
+ const result = new Function(fullCode)();
20
+ if (result.default) {
21
+ Object.assign(result, result.default);
22
+ delete result.default;
23
+ }
24
+
25
+ return result;
26
+ }
27
+
28
+ /**
29
+ * Virtual entry plugin to generate files from each of the entries in the entry file
30
+ *
31
+ * @param {object} entries Entries object from the entry file
32
+ * @returns {object} Virtual entry plugin
33
+ */
34
+ function virtualEntryPlugin(entries) {
35
+ const keys = Object.keys(entries);
36
+
37
+ return {
38
+ name: 'virtual-entry-plugin', // this name will show up in logs and errors
39
+
40
+ resolveId: {
41
+ order: 'post',
42
+ handler(source) {
43
+ if (keys.includes(source)) {
44
+ return source;
45
+ }
46
+ return null; // other ids should be handled as usual
47
+ }
48
+ },
49
+
50
+ load(id) {
51
+ if (keys.includes(id)) {
52
+ return entries[id].map((entry) => `import '${entry}';`).join('\n');
53
+ }
54
+ return null; // other ids should be handled as usual
55
+ },
56
+ };
57
+ }
58
+
59
+ const watcherList = {};
60
+
61
+ // transformer class
62
+ class GulpRolldown extends Transform {
63
+
64
+ _build(file, cb, inputOptions, outputOptions) {
65
+ rolldown.build(inputOptions)
66
+ .then((result) => {
67
+ // Prevent gulp from outputing anything
68
+ cb();
69
+ })
70
+ .catch(err => {
71
+ process.nextTick(() => {
72
+ this.emit('error', new PluginError(PLUGIN_NAME, err))
73
+ cb()
74
+ });
75
+ });
76
+ }
77
+
78
+ _watch(file, cb, inputOptions, outputOptions) {
79
+ const watcher = watcherList[file.path] = rolldown.watch(inputOptions);
80
+
81
+ watcher.on('event', (event) => {
82
+ if (event.code === 'BUNDLE_END') {
83
+ event.result.close();
84
+
85
+ // Reload browser
86
+ browserSync.reload();
87
+ }
88
+ });
89
+
90
+ // Prevent gulp from outputing anything
91
+ cb();
92
+ }
93
+
94
+ _transform(file, encoding, cb) {
95
+ // Empty or unavailable files, not supported
96
+ if (file.isNull()) {
97
+ return cb(null, file)
98
+ }
99
+
100
+ // Stream, not supported
101
+ if (file.isStream()) {
102
+ return cb(new PluginError(PLUGIN_NAME, 'Streaming not supported'))
103
+ }
104
+
105
+ const entries = this.inputOptions.entries;
106
+
107
+ if (!file.path.endsWith(entries.name)) {
108
+ // Not an entry file, skip
109
+ return cb();
110
+ }
111
+
112
+ // Remove old watcher if exists
113
+ if (watcherList[file.path]) {
114
+ watcherList[file.path].close();
115
+ delete watcherList[file.path];
116
+ }
117
+
118
+ // Transform options
119
+ const fullDir = this.outputOptions.fullDir;
120
+ const inputOptions = Object.assign({}, this.inputOptions)
121
+ const outputOptions = Object.assign({}, this.outputOptions);
122
+
123
+ delete(inputOptions.entries);
124
+ delete(outputOptions.fullDir);
125
+
126
+ // Parse entry file
127
+ const entryContent = evalEntry(file.contents.toString());
128
+ if (!entryContent) {
129
+ // @TODO Couldn't read entry file, throw an error???
130
+ }
131
+
132
+ // Add code splitting with shared
133
+ if (entries.shared) {
134
+ outputOptions.codeSplitting = Object.assign({}, outputOptions.codeSplitting || {}, {
135
+ groups: [].concat(outputOptions.codeSplitting?.groups || [], [
136
+ {
137
+ name: entries.shared,
138
+ minShareCount: 3,
139
+ },
140
+ ]),
141
+ });
142
+ }
143
+
144
+ // Don't output hash for rolldown runtime and shared chunks
145
+ outputOptions.chunkFileNames = (info) => {
146
+ if ((entries.shared && info.name === entries.shared) || info.name === 'rolldown-runtime') {
147
+ return '[name].js';
148
+ } else {
149
+ return '[name]-[hash].js';
150
+ }
151
+ };
152
+
153
+ // Set input files
154
+ inputOptions.input = Object.keys(entryContent);
155
+ inputOptions.plugins = [
156
+ virtualEntryPlugin(entryContent),
157
+ ].concat(inputOptions.plugins || []);
158
+
159
+ // Set full paths when running watch or build
160
+ inputOptions.output = outputOptions;
161
+
162
+ if (global.production) {
163
+ this._build(file, cb, inputOptions);
164
+ } else {
165
+ this._watch(file, cb, inputOptions);
166
+ }
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Factory
172
+ *
173
+ * @param {object} inputOptions
174
+ * @param {object} outputOptions
175
+ * @returns
176
+ */
177
+ module.exports = function factory(inputOptions, outputOptions) {
178
+ const stream = new GulpRolldown({objectMode: true})
179
+
180
+ stream.inputOptions = inputOptions
181
+ stream.outputOptions = outputOptions
182
+
183
+ return stream
184
+ }
@@ -1,32 +0,0 @@
1
- /**
2
- * Plugin which adds to the dynamically imported JS files a version string at the end
3
- * which is the same as for original file name.
4
- */
5
- module.exports = class WebpackURLVersioningPlugin {
6
- apply(compiler) {
7
- compiler.hooks.afterPlugins.tap('URLVersioning', () => {
8
- compiler.hooks.thisCompilation.tap('URLVersioning', compilation => {
9
- const mainTemplate = compilation.mainTemplate;
10
-
11
- if (mainTemplate.hooks.localVars) {
12
- mainTemplate.hooks.localVars.tap('URLVersioning',(source, _chunk, _hash) => {
13
- if (source.indexOf('var version = ') === -1) {
14
- const startString = 'function jsonpScriptSrc(chunkId) {';
15
- const endString = '+ ".js"';
16
- const start = source.indexOf(startString);
17
- const end = start !== -1 ? source.indexOf(endString, start) : -1;
18
-
19
- if (start !== -1) {
20
- const offset = end + endString.length;
21
- return 'var version = document.currentScript.src && document.currentScript.src.match(/\\?.*/);' + source.substr(0, offset) + ' + (version ? version[0] : "")' + source.substr(offset);
22
- }
23
- }
24
-
25
- return source;
26
- });
27
- }
28
- });
29
- });
30
-
31
- }
32
- }
@@ -1,253 +0,0 @@
1
- // 2024-02-24, Kaspars Zuks: added support for dynamic entries (entry as a function)
2
- 'use strict';
3
-
4
- var fancyLog = require('fancy-log');
5
- var PluginError = require('plugin-error');
6
- var supportsColor = require('supports-color');
7
- var File = require('vinyl');
8
- var MemoryFileSystem = require('memory-fs');
9
- var nodePath = require('path');
10
- var through = require('through');
11
- var ProgressPlugin = require('webpack/lib/ProgressPlugin');
12
- var clone = require('lodash.clone');
13
-
14
- var defaultStatsOptions = {
15
- colors: supportsColor.stdout.hasBasic,
16
- hash: false,
17
- timings: false,
18
- chunks: false,
19
- chunkModules: false,
20
- modules: false,
21
- children: true,
22
- version: true,
23
- cached: false,
24
- cachedAssets: false,
25
- reasons: false,
26
- source: false,
27
- errorDetails: false
28
- };
29
-
30
- module.exports = function (options, wp, done) {
31
- options = clone(options) || {};
32
- var config = options.config || options;
33
- var cache = {};
34
-
35
- // Webpack 4 doesn't support the `quiet` attribute, however supports
36
- // setting `stats` to a string within an array of configurations
37
- // (errors-only|minimal|none|normal|verbose) or an object with an absurd
38
- // amount of config
39
- const isSilent = options.quiet || (typeof options.stats === 'string' && (options.stats.match(/^(errors-only|minimal|none)$/)));
40
-
41
- if (typeof done !== 'function') {
42
- var callingDone = false;
43
- done = function (err, stats) {
44
- if (err) {
45
- // The err is here just to match the API but isnt used
46
- return;
47
- }
48
- stats = stats || {};
49
- if (isSilent || callingDone) {
50
- return;
51
- }
52
-
53
- // Debounce output a little for when in watch mode
54
- if (options.watch) {
55
- callingDone = true;
56
- setTimeout(function () {
57
- callingDone = false;
58
- }, 500);
59
- }
60
-
61
- if (options.verbose) {
62
- fancyLog(stats.toString({
63
- colors: supportsColor.stdout.hasBasic
64
- }));
65
- } else {
66
- var statsOptions = (options && options.stats) || {};
67
-
68
- if (typeof statsOptions === 'object') {
69
- Object.keys(defaultStatsOptions).forEach(function (key) {
70
- if (typeof statsOptions[key] === 'undefined') {
71
- statsOptions[key] = defaultStatsOptions[key];
72
- }
73
- });
74
- }
75
- var statusLog = stats.toString(statsOptions);
76
- if (statusLog) {
77
- fancyLog(statusLog);
78
- }
79
- }
80
- };
81
- }
82
-
83
- var webpack = wp || require('webpack');
84
- var entry = [];
85
- var entries = Object.create(null);
86
-
87
- var stream = through(function (file) {
88
- if (file.isNull()) {
89
- return;
90
- }
91
- if ('named' in file) {
92
- if (!Array.isArray(entries[file.named])) {
93
- entries[file.named] = [];
94
- }
95
- entries[file.named].push(file.path);
96
- } else {
97
- entry = entry || [];
98
- entry.push(file.path);
99
- }
100
- }, function () {
101
- var self = this;
102
- var handleConfig = function (config) {
103
- config.output = config.output || {};
104
- config.watch = !!options.watch;
105
-
106
- // Determine pipe'd in entry
107
- if (Object.keys(entries).length > 0) {
108
- entry = entries;
109
- if (!config.output.filename) {
110
- // Better output default for multiple chunks
111
- config.output.filename = '[name].js';
112
- }
113
- } else if (entry.length < 2) {
114
- entry = entry[0] || entry;
115
- }
116
-
117
- config.entry = config.entry || entry;
118
- config.output.path = config.output.path || process.cwd();
119
- config.output.filename = config.output.filename || '[hash].js';
120
- config.watch = options.watch;
121
- entry = [];
122
-
123
- if (typeof config.entry !== 'function' && (!config.entry || config.entry.length < 1)) {
124
- fancyLog('webpack-stream - No files given; aborting compilation');
125
- self.emit('end');
126
- return false;
127
- }
128
- return true;
129
- };
130
-
131
- var succeeded;
132
- if (Array.isArray(config)) {
133
- for (var i = 0; i < config.length; i++) {
134
- succeeded = handleConfig(config[i]);
135
- if (!succeeded) {
136
- return false;
137
- }
138
- }
139
- } else {
140
- succeeded = handleConfig(config);
141
- if (!succeeded) {
142
- return false;
143
- }
144
- }
145
-
146
- // Cache compiler for future use
147
- var compiler = cache.compiler || webpack(config);
148
- cache.compiler = compiler;
149
-
150
- const callback = function (err, stats) {
151
- if (err) {
152
- self.emit('error', new PluginError('webpack-stream', err));
153
- return;
154
- }
155
- var jsonStats = stats ? stats.toJson() || {} : {};
156
- var errors = jsonStats.errors || [];
157
- if (errors.length) {
158
- var errorMessage = errors.join('\n');
159
- var compilationError = new PluginError('webpack-stream', errorMessage);
160
- if (!options.watch) {
161
- self.emit('error', compilationError);
162
- }
163
- self.emit('compilation-error', compilationError);
164
- }
165
- if (!options.watch) {
166
- self.queue(null);
167
- }
168
- done(err, stats);
169
- if (options.watch && !isSilent) {
170
- fancyLog('webpack is watching for changes');
171
- }
172
- };
173
-
174
- if (options.watch) {
175
- const watchOptions = options.watchOptions || {};
176
- compiler.watch(watchOptions, callback);
177
- } else {
178
- compiler.run(callback);
179
- }
180
-
181
- var handleCompiler = function (compiler) {
182
- if (options.progress) {
183
- (new ProgressPlugin(function (percentage, msg) {
184
- percentage = Math.floor(percentage * 100);
185
- msg = percentage + '% ' + msg;
186
- if (percentage < 10) msg = ' ' + msg;
187
- fancyLog('webpack', msg);
188
- })).apply(compiler);
189
- }
190
-
191
- cache.mfs = cache.mfs || new MemoryFileSystem();
192
-
193
- var fs = compiler.outputFileSystem = cache.mfs;
194
-
195
- var afterEmitPlugin = compiler.hooks
196
- // Webpack 4
197
- ? function (callback) { compiler.hooks.afterEmit.tapAsync('WebpackStream', callback); }
198
- // Webpack 2/3
199
- : function (callback) { compiler.plugin('after-emit', callback); };
200
-
201
- afterEmitPlugin(function (compilation, callback) {
202
- Object.keys(compilation.assets).forEach(function (outname) {
203
- if (compilation.assets[outname].emitted) {
204
- var file = prepareFile(fs, compiler, outname);
205
- self.queue(file);
206
- }
207
- });
208
- callback();
209
- });
210
- };
211
-
212
- if (Array.isArray(options.config)) {
213
- compiler.compilers.forEach(function (compiler) {
214
- handleCompiler(compiler);
215
- });
216
- } else {
217
- handleCompiler(compiler);
218
- }
219
- });
220
-
221
- // If entry point manually specified, trigger that
222
- var hasEntry = Array.isArray(config)
223
- ? config.some(function (c) { return c.entry; })
224
- : config.entry;
225
- if (hasEntry) {
226
- stream.end();
227
- }
228
-
229
- return stream;
230
- };
231
-
232
- function prepareFile (fs, compiler, outname) {
233
- var path = fs.join(compiler.outputPath, outname);
234
- if (path.indexOf('?') !== -1) {
235
- path = path.split('?')[0];
236
- }
237
-
238
- var contents = fs.readFileSync(path);
239
-
240
- var file = new File({
241
- base: compiler.outputPath,
242
- path: nodePath.join(compiler.outputPath, outname),
243
- contents: contents
244
- });
245
- return file;
246
- }
247
-
248
- // Expose webpack if asked
249
- Object.defineProperty(module.exports, 'webpack', {
250
- get: function () {
251
- return require('webpack');
252
- }
253
- });