@videinfra/static-website-builder 2.0.0-beta.3 → 2.0.0

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.
@@ -0,0 +1,39 @@
1
+ import { defineConfig } from "eslint/config";
2
+
3
+ export default defineConfig([
4
+ {
5
+ env: {
6
+ "browser": true,
7
+ "commonjs": true,
8
+ "es6": true,
9
+ "jquery": true
10
+ },
11
+ extends: "eslint:recommended",
12
+ parserOptions: {
13
+ "sourceType": "module"
14
+ },
15
+ rules: {
16
+ "linebreak-style": [
17
+ "error",
18
+ "unix"
19
+ ],
20
+ "quotes": [
21
+ "error",
22
+ "single"
23
+ ],
24
+ "semi": [
25
+ "error",
26
+ "always"
27
+ ],
28
+ "no-console": [
29
+ "warn", { "allow": ["warn", "error"] }
30
+ ],
31
+ "no-debugger": [
32
+ "warn"
33
+ ],
34
+ "no-unused-vars": [
35
+ "warn"
36
+ ]
37
+ }
38
+ },
39
+ ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@videinfra/static-website-builder",
3
- "version": "2.0.0-beta.3",
3
+ "version": "2.0.0",
4
4
  "description": "Customizable static site project builder",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -1,4 +1,5 @@
1
1
  import { getTaskConfig } from '../../../lib/get-config.js';
2
+ import { loadEnvData } from '../../../tasks/env/get-env.js';
2
3
  import preposition_nbsp from './preposition_nbsp.js';
3
4
 
4
5
  const exports = [];
@@ -32,19 +33,21 @@ exports.push({
32
33
 
33
34
  /**
34
35
  * Version filter
35
- * Adds a random version string to the url
36
+ * Adds a version string to the url
36
37
  *
37
38
  * @example
38
39
  * {{ '/images/px.gif' | version }}
39
40
  * Output: /images/px.gif?dshnv
40
41
  */
41
42
 
42
- const version = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
43
-
44
43
  exports.push({
45
44
  name: 'version',
46
45
  func: function (path) {
47
46
  if (!getTaskConfig('html', 'version')) return path;
47
+ const envData = loadEnvData();
48
+ const assetVersion = envData['ASSETS_VERSION'];
49
+
50
+ if (!assetVersion) return path;
48
51
 
49
52
  const normalizedPath = (path || path === 0 ? String(path) : '');
50
53
  const parts = normalizedPath.match(/^([^?#]*)(\?[^#]*)?(#.*)?$/i);
@@ -52,7 +55,7 @@ exports.push({
52
55
  const params = parts[2] || '';
53
56
  const hash = parts[3] || '';
54
57
 
55
- return pathname + params + (params ? '&' : '?') + version + hash;
58
+ return pathname + params + (params ? '&v=' : '?v=') + assetVersion + hash;
56
59
  }
57
60
  });
58
61
 
@@ -1,4 +1,5 @@
1
1
  import dotenv from 'dotenv';
2
+ import nanomemoize from 'nano-memoize';
2
3
  import { getPathConfig, getProjectPath } from '../../lib/get-path.js';
3
4
  import { getTaskConfig } from '../../lib/get-config.js';
4
5
 
@@ -23,13 +24,12 @@ function normalizeTwigVariable(value) {
23
24
  }
24
25
  }
25
26
 
26
- function getEnvData() {
27
+ /**
28
+ * Load data from the .env files
29
+ * @returns {object} List of environment variables
30
+ */
31
+ export const loadEnvData = nanomemoize.nanomemoize(function () {
27
32
  const envVariables = {};
28
- const twigVariables = {};
29
- const scssVariables = { env: { _tmp: 1 } }; // _tmp is used to avoid SCSS error if object is empty
30
- const jsVariables = {};
31
- const envOutVariables = {};
32
-
33
33
  const envFiles = getPathConfig().env.map((path) => getProjectPath(path));
34
34
 
35
35
  dotenv.config({
@@ -40,6 +40,23 @@ function getEnvData() {
40
40
  quiet: true,
41
41
  });
42
42
 
43
+ // Set assets version if it doesn't exist
44
+ envVariables['ASSETS_VERSION'] = envVariables['ASSETS_VERSION'] || String(Math.floor(Date.now() / 1000));
45
+
46
+ return envVariables;
47
+ });
48
+
49
+ /**
50
+ * Returns environment variables mapped to the specified names
51
+ * @returns {object} Mapped environment variables
52
+ */
53
+ export default function getEnvData() {
54
+ const envVariables = loadEnvData();
55
+ const twigVariables = {};
56
+ const scssVariables = { env: { _tmp: 1 } }; // _tmp is used to avoid SCSS error if object is empty
57
+ const jsVariables = {};
58
+ const envOutVariables = {};
59
+
43
60
  // Remap property names
44
61
  const map = getTaskConfig('env', 'map');
45
62
 
@@ -62,5 +79,3 @@ function getEnvData() {
62
79
  env: envOutVariables,
63
80
  };
64
81
  }
65
-
66
- export default getEnvData;
@@ -1,6 +1,6 @@
1
1
  import { getDestPath, getBuilderPath, getProjectPath, getSourcePath } from '../../lib/get-path.js';
2
2
  import merge from '../../lib/merge.js';
3
- import getEnvData from '../env/get-env.js';
3
+ import getEnvData, { loadEnvData } from '../env/get-env.js';
4
4
  import get from 'lodash/get.js';
5
5
  import cloneDeep from 'lodash/cloneDeep.js';
6
6
  import replace from '@rollup/plugin-replace';
@@ -52,6 +52,20 @@ export default function preprocessJavascriptsConfig(config, fullConfig) {
52
52
  'process.env.NODE_ENV': JSON.stringify(global.production ? 'production' : 'development'),
53
53
  });
54
54
 
55
+ // Rewrite shared.js and rolldown-runtime.js to include cache busting asset version so that we could
56
+ // preload those assets using <link rel="preload" as="script" href="{{ asset(...) }}" />
57
+ const envData = loadEnvData();
58
+ const assetVersion = envData['ASSETS_VERSION'];
59
+ const replacements = {};
60
+
61
+ if (assetVersion) {
62
+ replacements['/rolldown-runtime.js'] = `/rolldown-runtime.js?v=${assetVersion}`;
63
+
64
+ if (entry.shared) {
65
+ replacements[`/${entry.shared}.js`] = `/${entry.shared}.js?v=${assetVersion}`;
66
+ }
67
+ }
68
+
55
69
  const buildConfig = merge(entryConfig, {
56
70
  rolldown: {
57
71
  // Entries, this file is resolved by gulp-rolldown and converted into
@@ -62,8 +76,7 @@ export default function preprocessJavascriptsConfig(config, fullConfig) {
62
76
  replace({
63
77
  preventAssignment: true,
64
78
  ...envVariables,
65
- // './shared.js': './shared.js?rcujz',
66
- // './rolldown-runtime.js': './rolldown-runtime.js?rcujz',
79
+ ...replacements,
67
80
  }),
68
81
  ],
69
82
 
@@ -4,6 +4,9 @@ import PluginError from 'plugin-error';
4
4
  import { watch, build } from 'rolldown';
5
5
  import browserSync from 'browser-sync';
6
6
 
7
+ import virtualEntryPlugin from './plugin-virtual-entry.js';
8
+ import rawPlugin from './plugin-raw.js';
9
+
7
10
  const PLUGIN_NAME = 'gulp-starter-rolldown';
8
11
 
9
12
  /**
@@ -26,37 +29,6 @@ function evalEntry(code) {
26
29
  return result;
27
30
  }
28
31
 
29
- /**
30
- * Virtual entry plugin to generate files from each of the entries in the entry file
31
- *
32
- * @param {object} entries Entries object from the entry file
33
- * @returns {object} Virtual entry plugin
34
- */
35
- function virtualEntryPlugin(entries) {
36
- const keys = Object.keys(entries);
37
-
38
- return {
39
- name: 'virtual-entry-plugin', // this name will show up in logs and errors
40
-
41
- resolveId: {
42
- order: 'post',
43
- handler(source) {
44
- if (keys.includes(source)) {
45
- return source;
46
- }
47
- return null; // other ids should be handled as usual
48
- },
49
- },
50
-
51
- load(id) {
52
- if (keys.includes(id)) {
53
- return entries[id].map((entry) => `import '${entry}';`).join('\n');
54
- }
55
- return null; // other ids should be handled as usual
56
- },
57
- };
58
- }
59
-
60
32
  const watcherList = {};
61
33
 
62
34
  // transformer class
@@ -116,18 +88,13 @@ class GulpRolldown extends Transform {
116
88
  }
117
89
 
118
90
  // Transform options
119
- const fullDir = this.outputOptions.fullDir;
120
91
  const inputOptions = Object.assign({}, this.inputOptions);
121
92
  const outputOptions = Object.assign({}, this.outputOptions);
122
93
 
123
94
  delete inputOptions.entries;
124
- delete outputOptions.fullDir;
125
95
 
126
96
  // Parse entry file
127
97
  const entryContent = evalEntry(file.contents.toString());
128
- if (!entryContent) {
129
- // @TODO Couldn't read entry file, throw an error???
130
- }
131
98
 
132
99
  // Add code splitting with shared
133
100
  if (entries.shared) {
@@ -152,7 +119,7 @@ class GulpRolldown extends Transform {
152
119
 
153
120
  // Set input files
154
121
  inputOptions.input = Object.keys(entryContent);
155
- inputOptions.plugins = [virtualEntryPlugin(entryContent)].concat(inputOptions.plugins || []);
122
+ inputOptions.plugins = [rawPlugin(), virtualEntryPlugin(entryContent)].concat(inputOptions.plugins || []);
156
123
 
157
124
  // Set full paths when running watch or build
158
125
  inputOptions.output = outputOptions;
@@ -0,0 +1,17 @@
1
+ import fs from 'node:fs';
2
+
3
+ export default function rawPlugin() {
4
+ return {
5
+ name: 'raw',
6
+ load: {
7
+ filter: {
8
+ id: /\?raw$/,
9
+ },
10
+ handler(id) {
11
+ const content = fs.readFileSync(id.replace('?raw', '')).toString('utf-8');
12
+ return `export default \`${content.replace(/`/g, '\\`')}\``;
13
+
14
+ }
15
+ },
16
+ };
17
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Virtual entry plugin to generate files from each of the entries in the entry file
3
+ *
4
+ * @param {object} entries Entries object from the entry file
5
+ * @returns {object} Virtual entry plugin
6
+ */
7
+ export default function virtualEntryPlugin(entries) {
8
+ const keys = Object.keys(entries);
9
+
10
+ return {
11
+ name: 'virtual-entry-plugin', // this name will show up in logs and errors
12
+
13
+ resolveId: {
14
+ order: 'post',
15
+ handler(source) {
16
+ if (keys.includes(source)) {
17
+ return source;
18
+ }
19
+ return null; // other ids should be handled as usual
20
+ },
21
+ },
22
+
23
+ load(id) {
24
+ if (keys.includes(id)) {
25
+ return entries[id].map((entry) => `import '${entry}';`).join('\n');
26
+ }
27
+ return null; // other ids should be handled as usual
28
+ },
29
+ };
30
+ }
package/.eslintignore DELETED
@@ -1,2 +0,0 @@
1
- src/javascripts/_entries.json
2
- src/static/sw.js
package/.eslintrc.js DELETED
@@ -1,35 +0,0 @@
1
- export default {
2
- "env": {
3
- "browser": true,
4
- "commonjs": true,
5
- "es6": true,
6
- "jquery": true
7
- },
8
- "extends": "eslint:recommended",
9
- "parserOptions": {
10
- "sourceType": "module"
11
- },
12
- "rules": {
13
- "linebreak-style": [
14
- "error",
15
- "unix"
16
- ],
17
- "quotes": [
18
- "error",
19
- "single"
20
- ],
21
- "semi": [
22
- "error",
23
- "always"
24
- ],
25
- "no-console": [
26
- "warn", { "allow": ["warn", "error"] }
27
- ],
28
- "no-debugger": [
29
- "warn"
30
- ],
31
- "no-unused-vars": [
32
- "warn"
33
- ]
34
- }
35
- };