edge-functions 2.2.0-stage.1 → 2.2.0-stage.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/CHANGELOG.md +15 -0
- package/README.md +1 -1
- package/jest.config.e2e.js +8 -0
- package/jest.config.unit.js +7 -0
- package/lib/build/bundlers/bundler-base.js +102 -0
- package/lib/build/bundlers/esbuild/esbuild.config.js +2 -0
- package/lib/build/bundlers/esbuild/index.js +46 -33
- package/lib/build/bundlers/esbuild/index.test.js +90 -0
- package/lib/build/bundlers/esbuild/plugins/node-polyfills/index.js +92 -131
- package/lib/build/bundlers/esbuild/plugins/node-polyfills/index.test.js +38 -0
- package/lib/build/bundlers/polyfills/node/_empty.js +0 -0
- package/lib/build/bundlers/polyfills/node/crypto.js +70 -0
- package/lib/build/bundlers/polyfills/node/globals/buffer.js +4 -0
- package/lib/build/bundlers/polyfills/node/globals/path-dirname.js +6 -0
- package/lib/build/{polyfills → bundlers/polyfills}/node/globals/process.js +76 -24
- package/lib/build/bundlers/polyfills/polyfills-manager.js +138 -0
- package/lib/build/bundlers/{esbuild/plugins/node-polyfills/node-pollyfills-paths.test.js → polyfills/polyfills-manager.test.js} +34 -21
- package/lib/build/bundlers/webpack/index.js +44 -28
- package/lib/build/bundlers/webpack/index.test.js +101 -0
- package/lib/build/bundlers/webpack/plugins/node-polyfills/index.js +65 -0
- package/lib/build/bundlers/webpack/plugins/node-polyfills/index.test.js +55 -0
- package/lib/build/bundlers/webpack/webpack.config.js +31 -2
- package/lib/build/dispatcher/dispatcher.js +203 -118
- package/lib/build/dispatcher/dispatcher.test.js +0 -1
- package/lib/constants/messages/build.messages.js +4 -0
- package/lib/presets/custom/next/compute/config.js +2 -87
- package/lib/presets/custom/next/compute/node/custom-server/12.3.1/server/require.js +3 -0
- package/package.json +12 -5
- package/lib/build/bundlers/esbuild/plugins/node-polyfills/node-polyfills-paths.js +0 -122
- /package/lib/build/{polyfills → bundlers/polyfills}/node/dns.js +0 -0
- /package/lib/build/{polyfills → bundlers/polyfills}/node/fs.js +0 -0
- /package/lib/build/{polyfills → bundlers/polyfills}/node/globals/navigator.js +0 -0
- /package/lib/build/{polyfills → bundlers/polyfills}/node/globals/performance.js +0 -0
- /package/lib/build/{polyfills → bundlers/polyfills}/node/http2.js +0 -0
- /package/lib/build/{polyfills → bundlers/polyfills}/node/module.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## [2.2.0-stage.2](https://github.com/aziontech/vulcan/compare/v2.2.0-stage.1...v2.2.0-stage.2) (2023-12-06)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* esbuild bundler improvements and changes ([5e668c4](https://github.com/aziontech/vulcan/commit/5e668c4c8c725de37102b776708a5641980842f4))
|
|
7
|
+
* improvements bundlers ([d546697](https://github.com/aziontech/vulcan/commit/d546697154b61124b947fff347b494dc474b7c36))
|
|
8
|
+
* initial code for organizing polyfill plugins ([2212272](https://github.com/aziontech/vulcan/commit/22122729bbdf0155357142c7fcbebd612d0509e3))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* esbuild plugin initial options ([8c84baa](https://github.com/aziontech/vulcan/commit/8c84baa117ed84a67202284d34abb05857083ec2))
|
|
14
|
+
* prevent reference sharing in config ([98b8caa](https://github.com/aziontech/vulcan/commit/98b8caa526e554401aeec2afed2dd126b29994f0))
|
|
15
|
+
|
|
1
16
|
## [2.2.0-stage.1](https://github.com/aziontech/vulcan/compare/v2.1.0...v2.2.0-stage.1) (2023-12-05)
|
|
2
17
|
|
|
3
18
|
|
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ Defines which build tool to use. The available options are `esbuild` and `webpac
|
|
|
108
108
|
**Type:** Boolean
|
|
109
109
|
|
|
110
110
|
**Description:**
|
|
111
|
-
Determines
|
|
111
|
+
Determines whether Node.js polyfills should be applied. This is useful for projects that leverage specific Node.js functionality but target environments without these built-in features. The use of useNodePolyfills is ignored when used in mode `deliver` presets, as Node.js features must be resolved at build time by the framework process itself.
|
|
112
112
|
|
|
113
113
|
### UseOwnWorker
|
|
114
114
|
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Messages } from '#constants';
|
|
2
|
+
import { feedback } from '#utils';
|
|
3
|
+
import merge from 'lodash.merge';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Base class for a bundler.
|
|
7
|
+
* @class
|
|
8
|
+
*/
|
|
9
|
+
class BundlerBase {
|
|
10
|
+
/**
|
|
11
|
+
* Represents a configuration object.
|
|
12
|
+
* @typedef {object} BuilderConfig
|
|
13
|
+
* @property {string} entry - The entry point for the configuration
|
|
14
|
+
* @property {string} buildId - The build ID
|
|
15
|
+
* @property {boolean} useNodePolyfills - Indicates if Node polyfills are being used
|
|
16
|
+
* @property {boolean} useOwnWorker - Indicates if a custom worker is being used
|
|
17
|
+
* @property {object} custom - Custom configuration.
|
|
18
|
+
* @property {*} localCustom - Local custom data
|
|
19
|
+
* @property {*} preset - The preset configuration
|
|
20
|
+
* @property {string} contentToInject - Content to inject
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {BuilderConfig} builderConfig - Constructor configuration.
|
|
25
|
+
*/
|
|
26
|
+
constructor(builderConfig) {
|
|
27
|
+
/**
|
|
28
|
+
* Constructor configuration.
|
|
29
|
+
* @type {BuilderConfig}
|
|
30
|
+
*/
|
|
31
|
+
this.builderConfig = builderConfig;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Custom configuration from the preset.
|
|
35
|
+
* @type {object}
|
|
36
|
+
*/
|
|
37
|
+
this.customConfigPreset = builderConfig.custom;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Local custom configuration.
|
|
41
|
+
* @type {object}
|
|
42
|
+
*/
|
|
43
|
+
this.customConfigLocal = builderConfig.localCustom;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Preset mode. e.g deliver | mode
|
|
47
|
+
* @type {object}
|
|
48
|
+
*/
|
|
49
|
+
this.presetMode = builderConfig?.preset?.mode;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Executes the plugin modification logic.
|
|
54
|
+
* This method can be overridden by subclasses.
|
|
55
|
+
* @returns {Promise<void>}
|
|
56
|
+
* @abstract
|
|
57
|
+
*/
|
|
58
|
+
// eslint-disable-next-line class-methods-use-this
|
|
59
|
+
async run() {
|
|
60
|
+
// Implement plugin modification logic here
|
|
61
|
+
// This method can be overridden by subclasses
|
|
62
|
+
// as it does not require the use of `this`
|
|
63
|
+
// eslint-disable-next-line class-methods-use-this
|
|
64
|
+
throw new Error('Running BundlerBase run method');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Applies the configuration.
|
|
69
|
+
* @param {object} config - Configuration to be applies.
|
|
70
|
+
* @returns {object} - The apply configuration.
|
|
71
|
+
* @abstract
|
|
72
|
+
*/
|
|
73
|
+
// eslint-disable-next-line class-methods-use-this
|
|
74
|
+
applyConfig(config) {
|
|
75
|
+
// The ESLint error is being ignored for this method
|
|
76
|
+
// as it does not require the use of `this`
|
|
77
|
+
return config;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Merges the configuration with the current configuration.
|
|
82
|
+
* @param {object} config - Configuration to be merged.
|
|
83
|
+
* @returns {object} - The merged configuration.
|
|
84
|
+
*/
|
|
85
|
+
mergeConfig(config = {}) {
|
|
86
|
+
const isDeliverMode = this.presetMode === 'deliver';
|
|
87
|
+
// waring mode deliver when useNodePolyfills
|
|
88
|
+
if (this.builderConfig.useNodePolyfills && isDeliverMode) {
|
|
89
|
+
feedback.build.warn(
|
|
90
|
+
Messages.build.warning.use_node_polyfill_mode_deliver,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
const hasCustomConfig = Object.keys(this.customConfigPreset).length > 0;
|
|
94
|
+
const hasCustomConfigLocal = Object.keys(this.customConfigLocal).length > 0;
|
|
95
|
+
if (hasCustomConfig || hasCustomConfigLocal) {
|
|
96
|
+
return merge(config, this.customConfigPreset, this.customConfigLocal);
|
|
97
|
+
}
|
|
98
|
+
return config;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export default BundlerBase;
|
|
@@ -1,59 +1,72 @@
|
|
|
1
1
|
import * as esbuild from 'esbuild';
|
|
2
|
-
import
|
|
2
|
+
import lodash from 'lodash';
|
|
3
3
|
|
|
4
|
-
import { debug } from '#utils';
|
|
5
4
|
import { Messages } from '#constants';
|
|
5
|
+
import { debug } from '#utils';
|
|
6
6
|
|
|
7
|
+
import BundlerBase from '../bundler-base.js';
|
|
7
8
|
import AzionEsbuildConfig from './esbuild.config.js';
|
|
8
|
-
import
|
|
9
|
+
import ESBuildNodeModulePlugin from './plugins/node-polyfills/index.js';
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
let config = AzionEsbuildConfig;
|
|
11
|
+
/**
|
|
12
|
+
* Class representing an ESBuild bundler, extending BundlerBase.
|
|
13
|
+
*/
|
|
14
|
+
class Esbuild extends BundlerBase {
|
|
15
|
+
/**
|
|
16
|
+
* Asynchronous method to run the ESBuild bundler.
|
|
17
|
+
*/
|
|
18
|
+
async run() {
|
|
19
|
+
let config = lodash.cloneDeep(AzionEsbuildConfig);
|
|
19
20
|
config.entryPoints = [this.builderConfig.entry];
|
|
20
21
|
config.define = {
|
|
21
22
|
AZION_VERSION_ID: JSON.stringify(this.builderConfig.buildId),
|
|
22
23
|
};
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
if (!config.plugins) config.plugins = [];
|
|
26
|
+
|
|
27
|
+
// merge config common
|
|
28
|
+
config = super.mergeConfig(config);
|
|
29
|
+
config = this.applyConfig(config);
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
await esbuild.build(config);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
debug.error(error);
|
|
35
|
+
throw Error(Messages.build.error.vulcan_build_failed);
|
|
27
36
|
}
|
|
37
|
+
}
|
|
28
38
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Applies specific configurations to the ESBuild config.
|
|
41
|
+
* @param {object} config - ESBuild configuration object.
|
|
42
|
+
* @returns {object} - Updated ESBuild configuration object.
|
|
43
|
+
*/
|
|
44
|
+
applyConfig(config) {
|
|
45
|
+
const updatedConfig = { ...config };
|
|
46
|
+
// use polyfill with useNodePolyfills and preset mode compute
|
|
47
|
+
const useNodePolyfills =
|
|
48
|
+
(this.builderConfig?.useNodePolyfills ||
|
|
49
|
+
this.customConfigPreset?.useNodePolyfills ||
|
|
50
|
+
this.customConfigLocal?.useNodePolyfills) &&
|
|
51
|
+
this.presetMode === 'compute';
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
if (useNodePolyfills) {
|
|
54
|
+
if (!updatedConfig.plugins) updatedConfig.plugins = [];
|
|
55
|
+
updatedConfig.plugins.push(ESBuildNodeModulePlugin());
|
|
37
56
|
}
|
|
38
57
|
|
|
39
58
|
// inject content in worker initial code.
|
|
40
59
|
if (this.builderConfig.contentToInject) {
|
|
41
60
|
const workerInitContent = this.builderConfig.contentToInject;
|
|
42
61
|
|
|
43
|
-
if (
|
|
44
|
-
|
|
62
|
+
if (updatedConfig.banner?.js) {
|
|
63
|
+
updatedConfig.banner.js = `${updatedConfig.banner.js} ${workerInitContent}`;
|
|
45
64
|
} else {
|
|
46
|
-
|
|
65
|
+
updatedConfig.banner = { js: workerInitContent };
|
|
47
66
|
}
|
|
48
67
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
await esbuild.build(config);
|
|
52
|
-
} catch (error) {
|
|
53
|
-
debug.error(error);
|
|
54
|
-
throw Error(Messages.build.error.vulcan_build_failed);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
68
|
+
return updatedConfig;
|
|
69
|
+
}
|
|
57
70
|
}
|
|
58
71
|
|
|
59
72
|
export default Esbuild;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import tmp from 'tmp';
|
|
3
|
+
import Esbuild from './index.js';
|
|
4
|
+
import AzionEsbuildConfig from './esbuild.config.js';
|
|
5
|
+
|
|
6
|
+
// IN MILESECONDS
|
|
7
|
+
const TIMEOUT = 20000;
|
|
8
|
+
|
|
9
|
+
describe('Esbuild Bundler', () => {
|
|
10
|
+
let tmpDir;
|
|
11
|
+
let tmpEntry;
|
|
12
|
+
let tmpOutput;
|
|
13
|
+
|
|
14
|
+
beforeEach(async () => {
|
|
15
|
+
tmpDir = tmp.dirSync();
|
|
16
|
+
tmpEntry = tmp.fileSync({
|
|
17
|
+
postfix: '.js',
|
|
18
|
+
dir: tmpDir.name,
|
|
19
|
+
name: 'entry.js',
|
|
20
|
+
});
|
|
21
|
+
tmpOutput = tmp.fileSync({
|
|
22
|
+
postfix: '.js',
|
|
23
|
+
dir: tmpDir.name,
|
|
24
|
+
name: 'output.js',
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
afterEach(async () => {
|
|
29
|
+
tmpEntry.removeCallback();
|
|
30
|
+
tmpOutput.removeCallback();
|
|
31
|
+
tmpDir.removeCallback();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it(
|
|
35
|
+
'should execute the bundle successfully',
|
|
36
|
+
async () => {
|
|
37
|
+
const code = `import crypto from 'crypto';console.log(process.env.NODE_ENV);`;
|
|
38
|
+
await fs.promises.writeFile(tmpEntry.name, code);
|
|
39
|
+
|
|
40
|
+
const bundler = new Esbuild({
|
|
41
|
+
buildId: '12345',
|
|
42
|
+
custom: {},
|
|
43
|
+
entry: tmpEntry.name,
|
|
44
|
+
localCustom: {
|
|
45
|
+
outfile: tmpOutput.name,
|
|
46
|
+
minify: false,
|
|
47
|
+
},
|
|
48
|
+
useNodePolyfills: true,
|
|
49
|
+
useOwnWorker: false,
|
|
50
|
+
preset: {
|
|
51
|
+
name: 'javascript',
|
|
52
|
+
mode: 'compute',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
await bundler.run();
|
|
56
|
+
|
|
57
|
+
const result = fs.readFileSync(tmpOutput.name, 'utf-8');
|
|
58
|
+
|
|
59
|
+
expect(result).toContain('vulcan-node-modules-polyfills:crypto');
|
|
60
|
+
},
|
|
61
|
+
TIMEOUT,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
it(
|
|
65
|
+
'should merge the config, in this case optimization.minimize false',
|
|
66
|
+
async () => {
|
|
67
|
+
const bundler = new Esbuild({
|
|
68
|
+
buildId: '12345',
|
|
69
|
+
custom: {
|
|
70
|
+
minify: true,
|
|
71
|
+
},
|
|
72
|
+
entry: tmpEntry.name,
|
|
73
|
+
localCustom: {
|
|
74
|
+
outfile: tmpOutput.name,
|
|
75
|
+
minify: false,
|
|
76
|
+
},
|
|
77
|
+
useNodePolyfills: false,
|
|
78
|
+
useOwnWorker: false,
|
|
79
|
+
preset: {
|
|
80
|
+
name: 'javascript',
|
|
81
|
+
mode: 'compute',
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
let config = AzionEsbuildConfig;
|
|
85
|
+
config = bundler.mergeConfig(config);
|
|
86
|
+
expect(config?.minify).toBeFalsy();
|
|
87
|
+
},
|
|
88
|
+
TIMEOUT,
|
|
89
|
+
);
|
|
90
|
+
});
|
|
@@ -1,154 +1,115 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
// Based on https://github.com/remorses/esbuild-plugins/blob/master/node-modules-polyfill/src/index.ts
|
|
3
|
-
|
|
1
|
+
/* eslint-disable consistent-return */
|
|
4
2
|
import fs from 'fs';
|
|
5
3
|
import path from 'path';
|
|
6
|
-
|
|
7
|
-
import builtinsPolyfills from './node-polyfills-paths.js';
|
|
8
|
-
|
|
9
|
-
const NAME = 'node-modules-polyfills';
|
|
10
|
-
const NAMESPACE = NAME;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Remove ending slash
|
|
14
|
-
* @param {string} importee - the imported path
|
|
15
|
-
* @returns {string} the new path without ending slash
|
|
16
|
-
*/
|
|
17
|
-
function removeEndingSlash(importee) {
|
|
18
|
-
if (importee && importee.slice(-1) === '/') {
|
|
19
|
-
return importee.slice(0, -1);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return importee;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function escapeStringRegexp(string) {
|
|
26
|
-
if (typeof string !== 'string') {
|
|
27
|
-
throw new TypeError('Expected a string');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Escape characters with special meaning either inside or outside character sets.
|
|
31
|
-
// Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar.
|
|
32
|
-
return string.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d');
|
|
33
|
-
}
|
|
4
|
+
import PolyfillsManager from '../../../polyfills/polyfills-manager.js';
|
|
34
5
|
|
|
35
6
|
/**
|
|
36
|
-
*
|
|
37
|
-
* @
|
|
38
|
-
* @returns {string} the template
|
|
7
|
+
* ESBuild Node Module Plugin for polyfilling node modules.
|
|
8
|
+
* @returns {object} - ESBuild plugin object.
|
|
39
9
|
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
if (polyfill && polyfill.default) {
|
|
45
|
-
module.exports = polyfill.default
|
|
46
|
-
for (let k in polyfill) {
|
|
47
|
-
module.exports[k] = polyfill[k]
|
|
48
|
-
}
|
|
49
|
-
} else if (polyfill) {
|
|
50
|
-
module.exports = polyfill
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
`;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Plugin to use nodejs polyfills
|
|
59
|
-
* @param {object} options - Options to use with the plugin
|
|
60
|
-
* @returns {object} - the plugin
|
|
61
|
-
*/
|
|
62
|
-
export function NodeModulesPolyfillPlugin(options = {}) {
|
|
63
|
-
const { namespace = NAMESPACE, name = NAME } = options;
|
|
64
|
-
if (namespace.endsWith('commonjs')) {
|
|
65
|
-
throw new Error(`namespace ${namespace} must not end with commonjs`);
|
|
66
|
-
}
|
|
67
|
-
// this namespace is needed to make ES modules expose their default export to require:
|
|
68
|
-
// require('assert') will give you import('assert').default
|
|
69
|
-
const commonjsNamespace = `${namespace}-commonjs`;
|
|
70
|
-
const polyfilledBuiltins = builtinsPolyfills();
|
|
71
|
-
const polyfilledBuiltinsNames = [...polyfilledBuiltins.keys()];
|
|
10
|
+
const ESBuildNodeModulePlugin = () => {
|
|
11
|
+
const NAME = 'vulcan-node-modules-polyfills';
|
|
12
|
+
const NAMESPACE = NAME;
|
|
72
13
|
|
|
73
14
|
return {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Name and setup of the ESBuild plugin.
|
|
17
|
+
* @param {object} build - ESBuild build object.
|
|
18
|
+
*/
|
|
19
|
+
name: NAME,
|
|
20
|
+
setup: (build) => {
|
|
21
|
+
const polyfillManager = PolyfillsManager.buildPolyfills();
|
|
22
|
+
|
|
23
|
+
// build options
|
|
24
|
+
const options = build.initialOptions;
|
|
25
|
+
options.define = options.define || {};
|
|
26
|
+
if (!options.define?.global) {
|
|
27
|
+
options.define.global = 'globalThis';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// define env
|
|
31
|
+
options.define = {
|
|
32
|
+
...options.define,
|
|
33
|
+
'process.env.NODE_ENV': '"production"',
|
|
34
|
+
'process.env.NEXT_RUNTIME': JSON.stringify('edge'),
|
|
35
|
+
'process.env.NEXT_COMPUTE_JS': JSON.stringify(true),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// build inject
|
|
39
|
+
options.inject = options.inject || [];
|
|
40
|
+
if (polyfillManager.globals) {
|
|
41
|
+
[...polyfillManager.globals].forEach(([, value]) => {
|
|
42
|
+
options.inject.push(value);
|
|
43
|
+
});
|
|
81
44
|
}
|
|
82
45
|
|
|
83
|
-
// TODO these polyfill module cannot import anything, is that ok?
|
|
84
46
|
/**
|
|
85
|
-
*
|
|
86
|
-
* @param args
|
|
47
|
+
* Resolve callback for ESBuild.
|
|
48
|
+
* @param {object} args - Arguments object.
|
|
49
|
+
* @returns {object|undefined} - Object with path and namespace or undefined.
|
|
87
50
|
*/
|
|
88
|
-
async
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const resolved = polyfilledBuiltins.get(removeEndingSlash(argsPath));
|
|
94
|
-
const contents = await (
|
|
95
|
-
await fs.promises.readFile(resolved)
|
|
96
|
-
).toString();
|
|
97
|
-
const resolveDir = path.dirname(resolved);
|
|
98
|
-
|
|
99
|
-
if (isCommonjs) {
|
|
100
|
-
return {
|
|
101
|
-
loader: 'js',
|
|
102
|
-
contents: commonJsTemplate({
|
|
103
|
-
importPath: argsPath,
|
|
104
|
-
}),
|
|
105
|
-
resolveDir,
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
return {
|
|
109
|
-
loader: 'js',
|
|
110
|
-
contents,
|
|
111
|
-
resolveDir,
|
|
112
|
-
};
|
|
113
|
-
} catch (e) {
|
|
114
|
-
console.error('node-modules-polyfill', e);
|
|
115
|
-
return {
|
|
116
|
-
contents: 'export {}',
|
|
117
|
-
loader: 'js',
|
|
118
|
-
};
|
|
51
|
+
build.onResolve({ filter: /.*/ }, async (args) => {
|
|
52
|
+
const argsPath = args.path.replace(/^node:/, '');
|
|
53
|
+
if (!polyfillManager.libs.has(argsPath)) {
|
|
54
|
+
return;
|
|
119
55
|
}
|
|
120
|
-
}
|
|
121
|
-
onLoad({ filter: /.*/, namespace }, loader);
|
|
122
|
-
onLoad({ filter: /.*/, namespace: commonjsNamespace }, loader);
|
|
123
|
-
const filter = new RegExp(
|
|
124
|
-
[
|
|
125
|
-
...polyfilledBuiltinsNames,
|
|
126
|
-
...polyfilledBuiltinsNames.map((n) => `node:${n}`),
|
|
127
|
-
]
|
|
128
|
-
.map(escapeStringRegexp)
|
|
129
|
-
.join('|'), // TODO builtins could end with slash, keep in mind in regex
|
|
130
|
-
);
|
|
131
56
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
57
|
+
// alias bypass
|
|
58
|
+
options.alias = options.alias || {};
|
|
59
|
+
if (
|
|
60
|
+
Object.keys(options.alias)?.length > 0 &&
|
|
61
|
+
options?.alias[argsPath]
|
|
62
|
+
) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
135
65
|
|
|
136
|
-
|
|
66
|
+
// external bypass
|
|
67
|
+
if (
|
|
68
|
+
options?.external?.length > 0 &&
|
|
69
|
+
options?.external?.includes(argsPath)
|
|
70
|
+
) {
|
|
137
71
|
return;
|
|
138
72
|
}
|
|
139
73
|
|
|
140
|
-
|
|
74
|
+
return {
|
|
75
|
+
path: args.path,
|
|
76
|
+
namespace: NAMESPACE,
|
|
77
|
+
};
|
|
78
|
+
});
|
|
141
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Load callback for assets.
|
|
82
|
+
* @param {object} args - Arguments object.
|
|
83
|
+
* @returns {object} - Object with contents and loader type.
|
|
84
|
+
*/
|
|
85
|
+
build.onLoad({ filter: /\.(txt|html)/ }, async (args) => {
|
|
86
|
+
const contents = await fs.promises.readFile(args.path, 'utf8');
|
|
142
87
|
return {
|
|
143
|
-
|
|
144
|
-
|
|
88
|
+
contents,
|
|
89
|
+
loader: 'text',
|
|
145
90
|
};
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Load callback for node module files.
|
|
95
|
+
* @param {object} args - Arguments object.
|
|
96
|
+
* @returns {object} - Object with loader, contents, and resolve directory.
|
|
97
|
+
*/
|
|
98
|
+
build.onLoad({ filter: /.*/, namespace: NAMESPACE }, async (args) => {
|
|
99
|
+
const argsPath = args.path.replace(/^node:/, '');
|
|
100
|
+
|
|
101
|
+
const resolved = polyfillManager.libs.get(argsPath);
|
|
102
|
+
const contents = await fs.promises.readFile(resolved, 'utf8');
|
|
103
|
+
const resolveDir = path.dirname(resolved);
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
loader: 'js',
|
|
107
|
+
contents,
|
|
108
|
+
resolveDir,
|
|
109
|
+
};
|
|
110
|
+
});
|
|
149
111
|
},
|
|
150
112
|
};
|
|
151
|
-
}
|
|
113
|
+
};
|
|
152
114
|
|
|
153
|
-
export default
|
|
154
|
-
/* eslint-enable */
|
|
115
|
+
export default ESBuildNodeModulePlugin;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as esbuild from 'esbuild';
|
|
2
|
+
import ESBuildNodeModulePlugin from './index.js';
|
|
3
|
+
|
|
4
|
+
describe('Esbuild Node Plugin', () => {
|
|
5
|
+
it('should check the env (NODE_ENV) in define options', async () => {
|
|
6
|
+
const results = await esbuild.build({
|
|
7
|
+
write: false,
|
|
8
|
+
stdin: {
|
|
9
|
+
contents: 'console.log(process.env.NODE_ENV)',
|
|
10
|
+
},
|
|
11
|
+
plugins: [ESBuildNodeModulePlugin()],
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
expect(results.outputFiles.at(0)?.text.trim()).toContain(
|
|
15
|
+
'console.log("production");',
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should resolve global crypto polyfill', async () => {
|
|
20
|
+
const results = await esbuild.build({
|
|
21
|
+
write: false,
|
|
22
|
+
target: 'es2022',
|
|
23
|
+
format: 'esm',
|
|
24
|
+
platform: 'browser',
|
|
25
|
+
mainFields: ['browser', 'main', 'module'],
|
|
26
|
+
bundle: true,
|
|
27
|
+
minify: false,
|
|
28
|
+
stdin: {
|
|
29
|
+
contents: 'import crypto from "crypto";',
|
|
30
|
+
},
|
|
31
|
+
plugins: [ESBuildNodeModulePlugin()],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
expect(results.outputFiles.at(0)?.text.trim()).toContain(
|
|
35
|
+
'vulcan-node-modules-polyfills:crypto',
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
File without changes
|