@modern-js/node-bundle-require 1.2.3 → 1.3.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.
package/.eslintrc.js ADDED
@@ -0,0 +1,8 @@
1
+ module.exports = {
2
+ root: true,
3
+ extends: ['@modern-js'],
4
+ parserOptions: {
5
+ tsconfigRootDir: __dirname,
6
+ project: ['./tsconfig.json'],
7
+ },
8
+ };
package/CHANGELOG.md CHANGED
@@ -1,4 +1,27 @@
1
- # @modern-js/1.0.0-rc.19
1
+ # @modern-js/node-bundle-require
2
+
3
+ ## 1.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - b8599d09: fix: failed to generate webpack cache
8
+ - 6cffe99d: chore:
9
+ remove react eslint rules for `modern-js` rule set.
10
+ add .eslintrc for each package to speed up linting
11
+ - 04ae5262: chore: bump @modern-js/utils to v1.4.1 in dependencies
12
+ - 60f7d8bf: feat: add tests dir to npmignore
13
+
14
+ ## 1.3.0
15
+
16
+ ### Minor Changes
17
+
18
+ - d2d1d6b2: feat: support server config
19
+
20
+ ## 1.2.4
21
+
22
+ ### Patch Changes
23
+
24
+ - 8491b6dd: fix: optimise "types" exports from plugin
2
25
 
3
26
  ## 1.2.3
4
27
 
@@ -0,0 +1,131 @@
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
+
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
+
5
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+
7
+ import path from 'path';
8
+ import { fs, CONFIG_CACHE_DIR, createDebugger } from '@modern-js/utils';
9
+ import { nanoid } from 'nanoid';
10
+ import { build } from 'esbuild';
11
+ const debug = createDebugger('node-bundle');
12
+ const JS_EXT_RE = /\.(mjs|cjs|ts|js|tsx|jsx)$/; // Must not start with "/" or "./" or "../"
13
+ // "/test/node_modules/foo"
14
+ // "c:/node_modules/foo"
15
+
16
+ export const EXTERNAL_REGEXP = /^[^./]|^\.[^./]|^\.\.[^/]/;
17
+
18
+ function inferLoader(ext) {
19
+ if (ext === '.mjs' || ext === '.cjs') {
20
+ return 'js';
21
+ }
22
+
23
+ return ext.slice(1);
24
+ }
25
+
26
+ const defaultGetOutputFile = filepath => path.resolve(CONFIG_CACHE_DIR, `${filepath}-${Date.now()}.${nanoid()}.bundled.cjs`);
27
+
28
+ export async function bundle(filepath, options) {
29
+ if (!JS_EXT_RE.test(filepath)) {
30
+ throw new Error(`${filepath} is not a valid JS file`);
31
+ }
32
+
33
+ debug('bundle', filepath, options);
34
+ const getOutputFile = (options === null || options === void 0 ? void 0 : options.getOutputFile) || defaultGetOutputFile;
35
+ const outfile = getOutputFile(path.basename(filepath));
36
+ await build(_objectSpread(_objectSpread({
37
+ entryPoints: [filepath],
38
+ outfile,
39
+ format: 'cjs',
40
+ platform: 'node',
41
+ bundle: true,
42
+ // fix transforming error when the project's tsconfig.json
43
+ // sets `target: "es5"`
44
+ // reference: https://github.com/evanw/esbuild/releases/tag/v0.12.6
45
+ target: 'esnext'
46
+ }, options === null || options === void 0 ? void 0 : options.esbuildOptions), {}, {
47
+ plugins: [...((options === null || options === void 0 ? void 0 : options.esbuildPlugins) || []), // https://github.com/evanw/esbuild/issues/1051#issuecomment-806325487
48
+ {
49
+ name: 'native-node-modules',
50
+
51
+ setup(build) {
52
+ // If a ".node" file is imported within a module in the "file" namespace, resolve
53
+ // it to an absolute path and put it into the "node-file" virtual namespace.
54
+ build.onResolve({
55
+ filter: /\.node$/,
56
+ namespace: 'file'
57
+ }, args => ({
58
+ path: require.resolve(args.path, {
59
+ paths: [args.resolveDir]
60
+ }),
61
+ namespace: 'node-file'
62
+ })); // Files in the "node-file" virtual namespace call "require()" on the
63
+ // path from esbuild of the ".node" file in the output directory.
64
+
65
+ build.onLoad({
66
+ filter: /.*/,
67
+ namespace: 'node-file'
68
+ }, args => ({
69
+ contents: `
70
+ import path from ${JSON.stringify(args.path)}
71
+ try { module.exports = require(path) }
72
+ catch {}
73
+ `
74
+ })); // If a ".node" file is imported within a module in the "node-file" namespace, put
75
+ // it in the "file" namespace where esbuild's default loading behavior will handle
76
+ // it. It is already an absolute path since we resolved it to one above.
77
+
78
+ build.onResolve({
79
+ filter: /\.node$/,
80
+ namespace: 'node-file'
81
+ }, args => ({
82
+ path: args.path,
83
+ namespace: 'file'
84
+ })); // Tell esbuild's default loading behavior to use the "file" loader for
85
+ // these ".node" files.
86
+
87
+ const opts = build.initialOptions;
88
+ opts.loader = opts.loader || {};
89
+ opts.loader['.node'] = 'file';
90
+ }
91
+
92
+ }, {
93
+ name: 'replace-path',
94
+
95
+ setup(ctx) {
96
+ ctx.onLoad({
97
+ filter: JS_EXT_RE
98
+ }, async args => {
99
+ const contents = fs.readFileSync(args.path, 'utf-8');
100
+ return {
101
+ contents: contents.replace(/\b__filename\b/g, JSON.stringify(args.path)).replace(/\b__dirname\b/g, JSON.stringify(path.dirname(args.path))).replace(/\bimport\.meta\.url\b/g, JSON.stringify(`file://${args.path}`)),
102
+ loader: inferLoader(path.extname(args.path))
103
+ };
104
+ });
105
+ }
106
+
107
+ }, // https://github.com/evanw/esbuild/issues/619#issuecomment-751995294
108
+ {
109
+ name: 'make-all-packages-external',
110
+
111
+ setup(_build) {
112
+ _build.onResolve({
113
+ filter: EXTERNAL_REGEXP
114
+ }, args => {
115
+ let external = true; // FIXME: windows external entrypoint
116
+
117
+ if (args.kind === 'entry-point') {
118
+ external = false;
119
+ }
120
+
121
+ return {
122
+ path: args.path,
123
+ external
124
+ };
125
+ });
126
+ }
127
+
128
+ }]
129
+ }));
130
+ return outfile;
131
+ }
@@ -1,140 +1,30 @@
1
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
-
3
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
-
5
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
-
7
- import path from 'path';
8
1
  import { fs } from '@modern-js/utils';
9
- import { build } from 'esbuild';
10
- import { nanoid } from 'nanoid';
11
- const JS_EXT_RE = /\.(mjs|cjs|ts|js|tsx|jsx)$/; // Must not start with "/" or "./" or "../"
12
- // "/test/node_modules/foo"
13
- // "c:/node_modules/foo"
2
+ import { bundle } from "./bundle";
3
+ export { bundle };
14
4
 
15
- export const EXTERNAL_REGEXP = /^[^./]|^\.[^./]|^\.\.[^/]/;
16
- const CACHE_DIR = path.relative(process.cwd(), './node_modules/.node-bundle-require');
17
-
18
- function inferLoader(ext) {
19
- if (ext === '.mjs' || ext === '.cjs') {
20
- return 'js';
5
+ function deleteRequireCache(path) {
6
+ if (require.cache[path]) {
7
+ delete require.cache[path];
21
8
  }
22
9
 
23
- return ext.slice(1);
10
+ if (module.children) {
11
+ module.children = module.children.filter(item => item.filename !== path);
12
+ }
24
13
  }
25
14
 
26
- const defaultGetOutputFile = filepath => path.resolve(CACHE_DIR, `${filepath}-${Date.now()}.${nanoid()}.bundled.cjs`);
27
-
28
15
  export async function bundleRequire(filepath, options) {
29
- if (!JS_EXT_RE.test(filepath)) {
30
- throw new Error(`${filepath} is not a valid JS file`);
31
- }
32
-
33
- const getOutputFile = (options === null || options === void 0 ? void 0 : options.getOutputFile) || defaultGetOutputFile;
34
- const outfile = getOutputFile(filepath);
35
- await build(_objectSpread(_objectSpread({
36
- entryPoints: [filepath],
37
- outfile,
38
- format: 'cjs',
39
- platform: 'node',
40
- bundle: true,
41
- // fix transforming error when the project's tsconfig.json
42
- // sets `target: "es5"`
43
- // reference: https://github.com/evanw/esbuild/releases/tag/v0.12.6
44
- target: 'esnext'
45
- }, options === null || options === void 0 ? void 0 : options.esbuildOptions), {}, {
46
- plugins: [...((options === null || options === void 0 ? void 0 : options.esbuildPlugins) || []), // https://github.com/evanw/esbuild/issues/1051#issuecomment-806325487
47
- {
48
- name: 'native-node-modules',
49
-
50
- // eslint-disable-next-line @typescript-eslint/no-shadow
51
- setup(build) {
52
- // If a ".node" file is imported within a module in the "file" namespace, resolve
53
- // it to an absolute path and put it into the "node-file" virtual namespace.
54
- build.onResolve({
55
- filter: /\.node$/,
56
- namespace: 'file'
57
- }, args => ({
58
- path: require.resolve(args.path, {
59
- paths: [args.resolveDir]
60
- }),
61
- namespace: 'node-file'
62
- })); // Files in the "node-file" virtual namespace call "require()" on the
63
- // path from esbuild of the ".node" file in the output directory.
64
-
65
- build.onLoad({
66
- filter: /.*/,
67
- namespace: 'node-file'
68
- }, args => ({
69
- contents: `
70
- import path from ${JSON.stringify(args.path)}
71
- try { module.exports = require(path) }
72
- catch {}
73
- `
74
- })); // If a ".node" file is imported within a module in the "node-file" namespace, put
75
- // it in the "file" namespace where esbuild's default loading behavior will handle
76
- // it. It is already an absolute path since we resolved it to one above.
77
-
78
- build.onResolve({
79
- filter: /\.node$/,
80
- namespace: 'node-file'
81
- }, args => ({
82
- path: args.path,
83
- namespace: 'file'
84
- })); // Tell esbuild's default loading behavior to use the "file" loader for
85
- // these ".node" files.
86
-
87
- const opts = build.initialOptions;
88
- opts.loader = opts.loader || {};
89
- opts.loader['.node'] = 'file';
90
- }
91
-
92
- }, {
93
- name: 'replace-path',
94
-
95
- setup(ctx) {
96
- ctx.onLoad({
97
- filter: JS_EXT_RE
98
- }, async args => {
99
- const contents = fs.readFileSync(args.path, 'utf-8');
100
- return {
101
- contents: contents.replace(/\b__filename\b/g, JSON.stringify(args.path)).replace(/\b__dirname\b/g, JSON.stringify(path.dirname(args.path))).replace(/\bimport\.meta\.url\b/g, JSON.stringify(`file://${args.path}`)),
102
- loader: inferLoader(path.extname(args.path))
103
- };
104
- });
105
- }
106
-
107
- }, // https://github.com/evanw/esbuild/issues/619#issuecomment-751995294
108
- {
109
- name: 'make-all-packages-external',
110
-
111
- setup(_build) {
112
- _build.onResolve({
113
- filter: EXTERNAL_REGEXP
114
- }, args => {
115
- let external = true; // FIXME: windows external entrypoint
116
-
117
- if (args.kind === 'entry-point') {
118
- external = false;
119
- }
120
-
121
- return {
122
- path: args.path,
123
- external
124
- };
125
- });
126
- }
127
-
128
- }]
129
- }));
16
+ const configFile = await bundle(filepath, options);
130
17
  let mod;
131
18
  const req = (options === null || options === void 0 ? void 0 : options.require) || require;
132
19
 
133
20
  try {
134
- mod = await req(outfile);
21
+ mod = await req(configFile); // Webpack will check require history for persistent cache.
22
+ // If webpack can not resolve the file, the previous cache pack will become invalid.
23
+ // The bundled file is temporary, so we should clear the require history to avoid breaking the webpack cache.
24
+
25
+ deleteRequireCache(configFile);
135
26
  } finally {
136
- // Remove the outfile after executed
137
- fs.unlinkSync(outfile);
27
+ fs.unlinkSync(configFile);
138
28
  }
139
29
 
140
30
  return mod;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.EXTERNAL_REGEXP = void 0;
7
+ exports.bundle = bundle;
8
+
9
+ var _path = _interopRequireDefault(require("path"));
10
+
11
+ var _utils = require("@modern-js/utils");
12
+
13
+ var _nanoid = require("nanoid");
14
+
15
+ var _esbuild = require("esbuild");
16
+
17
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
+
19
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
20
+
21
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
22
+
23
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
24
+
25
+ const debug = (0, _utils.createDebugger)('node-bundle');
26
+ const JS_EXT_RE = /\.(mjs|cjs|ts|js|tsx|jsx)$/; // Must not start with "/" or "./" or "../"
27
+ // "/test/node_modules/foo"
28
+ // "c:/node_modules/foo"
29
+
30
+ const EXTERNAL_REGEXP = /^[^./]|^\.[^./]|^\.\.[^/]/;
31
+ exports.EXTERNAL_REGEXP = EXTERNAL_REGEXP;
32
+
33
+ function inferLoader(ext) {
34
+ if (ext === '.mjs' || ext === '.cjs') {
35
+ return 'js';
36
+ }
37
+
38
+ return ext.slice(1);
39
+ }
40
+
41
+ const defaultGetOutputFile = filepath => _path.default.resolve(_utils.CONFIG_CACHE_DIR, `${filepath}-${Date.now()}.${(0, _nanoid.nanoid)()}.bundled.cjs`);
42
+
43
+ async function bundle(filepath, options) {
44
+ if (!JS_EXT_RE.test(filepath)) {
45
+ throw new Error(`${filepath} is not a valid JS file`);
46
+ }
47
+
48
+ debug('bundle', filepath, options);
49
+ const getOutputFile = (options === null || options === void 0 ? void 0 : options.getOutputFile) || defaultGetOutputFile;
50
+ const outfile = getOutputFile(_path.default.basename(filepath));
51
+ await (0, _esbuild.build)(_objectSpread(_objectSpread({
52
+ entryPoints: [filepath],
53
+ outfile,
54
+ format: 'cjs',
55
+ platform: 'node',
56
+ bundle: true,
57
+ // fix transforming error when the project's tsconfig.json
58
+ // sets `target: "es5"`
59
+ // reference: https://github.com/evanw/esbuild/releases/tag/v0.12.6
60
+ target: 'esnext'
61
+ }, options === null || options === void 0 ? void 0 : options.esbuildOptions), {}, {
62
+ plugins: [...((options === null || options === void 0 ? void 0 : options.esbuildPlugins) || []), // https://github.com/evanw/esbuild/issues/1051#issuecomment-806325487
63
+ {
64
+ name: 'native-node-modules',
65
+
66
+ setup(build) {
67
+ // If a ".node" file is imported within a module in the "file" namespace, resolve
68
+ // it to an absolute path and put it into the "node-file" virtual namespace.
69
+ build.onResolve({
70
+ filter: /\.node$/,
71
+ namespace: 'file'
72
+ }, args => ({
73
+ path: require.resolve(args.path, {
74
+ paths: [args.resolveDir]
75
+ }),
76
+ namespace: 'node-file'
77
+ })); // Files in the "node-file" virtual namespace call "require()" on the
78
+ // path from esbuild of the ".node" file in the output directory.
79
+
80
+ build.onLoad({
81
+ filter: /.*/,
82
+ namespace: 'node-file'
83
+ }, args => ({
84
+ contents: `
85
+ import path from ${JSON.stringify(args.path)}
86
+ try { module.exports = require(path) }
87
+ catch {}
88
+ `
89
+ })); // If a ".node" file is imported within a module in the "node-file" namespace, put
90
+ // it in the "file" namespace where esbuild's default loading behavior will handle
91
+ // it. It is already an absolute path since we resolved it to one above.
92
+
93
+ build.onResolve({
94
+ filter: /\.node$/,
95
+ namespace: 'node-file'
96
+ }, args => ({
97
+ path: args.path,
98
+ namespace: 'file'
99
+ })); // Tell esbuild's default loading behavior to use the "file" loader for
100
+ // these ".node" files.
101
+
102
+ const opts = build.initialOptions;
103
+ opts.loader = opts.loader || {};
104
+ opts.loader['.node'] = 'file';
105
+ }
106
+
107
+ }, {
108
+ name: 'replace-path',
109
+
110
+ setup(ctx) {
111
+ ctx.onLoad({
112
+ filter: JS_EXT_RE
113
+ }, async args => {
114
+ const contents = _utils.fs.readFileSync(args.path, 'utf-8');
115
+
116
+ return {
117
+ contents: contents.replace(/\b__filename\b/g, JSON.stringify(args.path)).replace(/\b__dirname\b/g, JSON.stringify(_path.default.dirname(args.path))).replace(/\bimport\.meta\.url\b/g, JSON.stringify(`file://${args.path}`)),
118
+ loader: inferLoader(_path.default.extname(args.path))
119
+ };
120
+ });
121
+ }
122
+
123
+ }, // https://github.com/evanw/esbuild/issues/619#issuecomment-751995294
124
+ {
125
+ name: 'make-all-packages-external',
126
+
127
+ setup(_build) {
128
+ _build.onResolve({
129
+ filter: EXTERNAL_REGEXP
130
+ }, args => {
131
+ let external = true; // FIXME: windows external entrypoint
132
+
133
+ if (args.kind === 'entry-point') {
134
+ external = false;
135
+ }
136
+
137
+ return {
138
+ path: args.path,
139
+ external
140
+ };
141
+ });
142
+ }
143
+
144
+ }]
145
+ }));
146
+ return outfile;
147
+ }
@@ -3,155 +3,41 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.EXTERNAL_REGEXP = void 0;
6
+ Object.defineProperty(exports, "bundle", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _bundle.bundle;
10
+ }
11
+ });
7
12
  exports.bundleRequire = bundleRequire;
8
13
 
9
- var _path = _interopRequireDefault(require("path"));
10
-
11
14
  var _utils = require("@modern-js/utils");
12
15
 
13
- var _esbuild = require("esbuild");
14
-
15
- var _nanoid = require("nanoid");
16
-
17
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
-
19
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
20
-
21
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
16
+ var _bundle = require("./bundle");
22
17
 
23
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
24
-
25
- const JS_EXT_RE = /\.(mjs|cjs|ts|js|tsx|jsx)$/; // Must not start with "/" or "./" or "../"
26
- // "/test/node_modules/foo"
27
- // "c:/node_modules/foo"
28
-
29
- const EXTERNAL_REGEXP = /^[^./]|^\.[^./]|^\.\.[^/]/;
30
- exports.EXTERNAL_REGEXP = EXTERNAL_REGEXP;
31
-
32
- const CACHE_DIR = _path.default.relative(process.cwd(), './node_modules/.node-bundle-require');
33
-
34
- function inferLoader(ext) {
35
- if (ext === '.mjs' || ext === '.cjs') {
36
- return 'js';
18
+ function deleteRequireCache(path) {
19
+ if (require.cache[path]) {
20
+ delete require.cache[path];
37
21
  }
38
22
 
39
- return ext.slice(1);
23
+ if (module.children) {
24
+ module.children = module.children.filter(item => item.filename !== path);
25
+ }
40
26
  }
41
27
 
42
- const defaultGetOutputFile = filepath => _path.default.resolve(CACHE_DIR, `${filepath}-${Date.now()}.${(0, _nanoid.nanoid)()}.bundled.cjs`);
43
-
44
28
  async function bundleRequire(filepath, options) {
45
- if (!JS_EXT_RE.test(filepath)) {
46
- throw new Error(`${filepath} is not a valid JS file`);
47
- }
48
-
49
- const getOutputFile = (options === null || options === void 0 ? void 0 : options.getOutputFile) || defaultGetOutputFile;
50
- const outfile = getOutputFile(filepath);
51
- await (0, _esbuild.build)(_objectSpread(_objectSpread({
52
- entryPoints: [filepath],
53
- outfile,
54
- format: 'cjs',
55
- platform: 'node',
56
- bundle: true,
57
- // fix transforming error when the project's tsconfig.json
58
- // sets `target: "es5"`
59
- // reference: https://github.com/evanw/esbuild/releases/tag/v0.12.6
60
- target: 'esnext'
61
- }, options === null || options === void 0 ? void 0 : options.esbuildOptions), {}, {
62
- plugins: [...((options === null || options === void 0 ? void 0 : options.esbuildPlugins) || []), // https://github.com/evanw/esbuild/issues/1051#issuecomment-806325487
63
- {
64
- name: 'native-node-modules',
65
-
66
- // eslint-disable-next-line @typescript-eslint/no-shadow
67
- setup(build) {
68
- // If a ".node" file is imported within a module in the "file" namespace, resolve
69
- // it to an absolute path and put it into the "node-file" virtual namespace.
70
- build.onResolve({
71
- filter: /\.node$/,
72
- namespace: 'file'
73
- }, args => ({
74
- path: require.resolve(args.path, {
75
- paths: [args.resolveDir]
76
- }),
77
- namespace: 'node-file'
78
- })); // Files in the "node-file" virtual namespace call "require()" on the
79
- // path from esbuild of the ".node" file in the output directory.
80
-
81
- build.onLoad({
82
- filter: /.*/,
83
- namespace: 'node-file'
84
- }, args => ({
85
- contents: `
86
- import path from ${JSON.stringify(args.path)}
87
- try { module.exports = require(path) }
88
- catch {}
89
- `
90
- })); // If a ".node" file is imported within a module in the "node-file" namespace, put
91
- // it in the "file" namespace where esbuild's default loading behavior will handle
92
- // it. It is already an absolute path since we resolved it to one above.
93
-
94
- build.onResolve({
95
- filter: /\.node$/,
96
- namespace: 'node-file'
97
- }, args => ({
98
- path: args.path,
99
- namespace: 'file'
100
- })); // Tell esbuild's default loading behavior to use the "file" loader for
101
- // these ".node" files.
102
-
103
- const opts = build.initialOptions;
104
- opts.loader = opts.loader || {};
105
- opts.loader['.node'] = 'file';
106
- }
107
-
108
- }, {
109
- name: 'replace-path',
110
-
111
- setup(ctx) {
112
- ctx.onLoad({
113
- filter: JS_EXT_RE
114
- }, async args => {
115
- const contents = _utils.fs.readFileSync(args.path, 'utf-8');
116
-
117
- return {
118
- contents: contents.replace(/\b__filename\b/g, JSON.stringify(args.path)).replace(/\b__dirname\b/g, JSON.stringify(_path.default.dirname(args.path))).replace(/\bimport\.meta\.url\b/g, JSON.stringify(`file://${args.path}`)),
119
- loader: inferLoader(_path.default.extname(args.path))
120
- };
121
- });
122
- }
123
-
124
- }, // https://github.com/evanw/esbuild/issues/619#issuecomment-751995294
125
- {
126
- name: 'make-all-packages-external',
127
-
128
- setup(_build) {
129
- _build.onResolve({
130
- filter: EXTERNAL_REGEXP
131
- }, args => {
132
- let external = true; // FIXME: windows external entrypoint
133
-
134
- if (args.kind === 'entry-point') {
135
- external = false;
136
- }
137
-
138
- return {
139
- path: args.path,
140
- external
141
- };
142
- });
143
- }
144
-
145
- }]
146
- }));
29
+ const configFile = await (0, _bundle.bundle)(filepath, options);
147
30
  let mod;
148
31
  const req = (options === null || options === void 0 ? void 0 : options.require) || require;
149
32
 
150
33
  try {
151
- mod = await req(outfile);
34
+ mod = await req(configFile); // Webpack will check require history for persistent cache.
35
+ // If webpack can not resolve the file, the previous cache pack will become invalid.
36
+ // The bundled file is temporary, so we should clear the require history to avoid breaking the webpack cache.
37
+
38
+ deleteRequireCache(configFile);
152
39
  } finally {
153
- // Remove the outfile after executed
154
- _utils.fs.unlinkSync(outfile);
40
+ _utils.fs.unlinkSync(configFile);
155
41
  }
156
42
 
157
43
  return mod;
@@ -0,0 +1,27 @@
1
+ import { Plugin, BuildOptions } from 'esbuild';
2
+ export declare const EXTERNAL_REGEXP: RegExp;
3
+ export interface Options {
4
+ /**
5
+ * The `require` function that is used to load the output file
6
+ * Default to the global `require` function
7
+ * This function can be asynchronous, i.e. returns a Promise
8
+ */
9
+ require?: (outfile: string) => any;
10
+ /**
11
+ * esbuild options
12
+ */
13
+
14
+ esbuildOptions?: BuildOptions;
15
+ /**
16
+ * esbuild plugin
17
+ */
18
+
19
+ esbuildPlugins?: Plugin[];
20
+ /**
21
+ * Get the path to the output file
22
+ * By default we simply replace the extension with `.bundled.cjs`
23
+ */
24
+
25
+ getOutputFile?: (filepath: string) => string;
26
+ }
27
+ export declare function bundle(filepath: string, options?: Options): Promise<string>;
@@ -1,27 +1,3 @@
1
- import { Plugin, BuildOptions } from 'esbuild';
2
- export declare const EXTERNAL_REGEXP: RegExp;
3
- export interface Options {
4
- /**
5
- * The `require` function that is used to load the output file
6
- * Default to the global `require` function
7
- * This function can be asynchronous, i.e. returns a Promise
8
- */
9
- require?: (outfile: string) => any;
10
- /**
11
- * esbuild options
12
- */
13
-
14
- esbuildOptions?: BuildOptions;
15
- /**
16
- * esbuild plugin
17
- */
18
-
19
- esbuildPlugins?: Plugin[];
20
- /**
21
- * Get the path to the output file
22
- * By default we simply replace the extension with `.bundled.cjs`
23
- */
24
-
25
- getOutputFile?: (filepath: string) => string;
26
- }
1
+ import { bundle, Options } from './bundle';
2
+ export { bundle };
27
3
  export declare function bundleRequire(filepath: string, options?: Options): Promise<any>;
package/jest.config.js CHANGED
@@ -2,7 +2,6 @@ const sharedConfig = require('@scripts/jest-config');
2
2
 
3
3
  /** @type {import('@jest/types').Config.InitialOptions} */
4
4
  module.exports = {
5
- // eslint-disable-next-line node/no-unsupported-features/es-syntax
6
5
  ...sharedConfig,
7
6
  rootDir: __dirname,
8
7
  };
package/modern.config.js CHANGED
@@ -1,2 +1,6 @@
1
1
  /** @type {import('@modern-js/module-tools').UserConfig} */
2
- module.exports = {};
2
+ module.exports = {
3
+ output: {
4
+ packageMode: 'node-js',
5
+ },
6
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modern-js/node-bundle-require",
3
- "version": "1.2.3",
3
+ "version": "1.3.1",
4
4
  "description": "The meta-framework suite designed from scratch for frontend-focused modern web development.",
5
5
  "homepage": "https://modernjs.dev",
6
6
  "bugs": "https://github.com/modern-js-dev/modern.js/issues",
@@ -25,28 +25,34 @@
25
25
  "require": "./dist/js/node/index.js"
26
26
  },
27
27
  "default": "./dist/js/treeshaking/index.js"
28
+ },
29
+ "./bundle": "./dist/js/node/bundle.js"
30
+ },
31
+ "typesVersions": {
32
+ "*": {
33
+ ".": [
34
+ "./dist/types/index.d.ts"
35
+ ],
36
+ "bundle": [
37
+ "./dist/types/bundle.d.ts"
38
+ ]
28
39
  }
29
40
  },
30
41
  "dependencies": {
31
42
  "@babel/runtime": "^7",
32
- "esbuild": "^0.13.8",
33
- "nanoid": "^3.3.1"
43
+ "esbuild": "^0.13.15",
44
+ "nanoid": "^3.3.2"
34
45
  },
35
46
  "devDependencies": {
47
+ "@modern-js/utils": "^1.5.0",
36
48
  "@scripts/build": "0.0.0",
37
- "@modern-js/utils": "^1.3.6",
49
+ "@scripts/jest-config": "0.0.0",
38
50
  "@types/jest": "^26.0.9",
39
51
  "@types/node": "^14",
40
- "typescript": "^4",
41
52
  "jest": "^27",
42
- "@scripts/jest-config": "0.0.0"
53
+ "typescript": "^4"
43
54
  },
44
55
  "sideEffects": false,
45
- "modernConfig": {
46
- "output": {
47
- "packageMode": "node-js"
48
- }
49
- },
50
56
  "publishConfig": {
51
57
  "registry": "https://registry.npmjs.org/",
52
58
  "access": "public"
@@ -1,6 +0,0 @@
1
- module.exports = {
2
- extends: '@modern-js',
3
- parserOptions: {
4
- project: require.resolve('./tsconfig.json'),
5
- },
6
- };
@@ -1,2 +0,0 @@
1
- export const filename: string = __filename;
2
- export const showFileName = () => filename;
@@ -1,5 +0,0 @@
1
- import * as a from './a';
2
-
3
- export default {
4
- a,
5
- };
@@ -1,26 +0,0 @@
1
- import path from 'path';
2
- import { bundleRequire, EXTERNAL_REGEXP } from '../src';
3
-
4
- test('require', async () => {
5
- const result = await bundleRequire(
6
- path.join(__dirname, './fixture/input.ts'),
7
- );
8
- // when tsconfig.json sets `compilerOptions.target` to `es5`
9
- // normally it will met error
10
- // So we need to manually set esbuild's target to esnext to avoid that
11
- // These two cases above use ES6+ ability, to test whether esbuild successfuly
12
- // works on non-ES5 files
13
- // reference: https://github.com/evanw/esbuild/releases/tag/v0.12.6
14
- expect(result.default.a.filename.endsWith('a.ts')).toEqual(true);
15
- expect(result.default.a.showFileName().endsWith('a.ts')).toEqual(true);
16
- });
17
-
18
- describe('external regexp', () => {
19
- expect(EXTERNAL_REGEXP.test('./test')).toBeFalsy();
20
- expect(EXTERNAL_REGEXP.test('/test')).toBeFalsy();
21
- expect(EXTERNAL_REGEXP.test('c:/foo')).toBeTruthy();
22
- expect(EXTERNAL_REGEXP.test('C:/foo')).toBeTruthy();
23
- expect(EXTERNAL_REGEXP.test('c:/node_modules/foo')).toBeTruthy();
24
- expect(EXTERNAL_REGEXP.test('foo')).toBeTruthy();
25
- expect(EXTERNAL_REGEXP.test('/test/node_modules')).toBeFalsy();
26
- });
@@ -1,2 +0,0 @@
1
- /// <reference types="@modern-js/module-tools/types" />
2
- /// <reference types="@modern-js/plugin-testing/type" />
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "@modern-js/tsconfig/base",
3
- "compilerOptions": {
4
- "declaration": false,
5
- "target": "es5",
6
- "jsx": "preserve",
7
- "baseUrl": "./",
8
- "paths": {}
9
- }
10
- }