Skip to content

Commit bd3fb1f

Browse files
feat: externalize node_modules (#7)
* feat: externalize node_modules * fix: webpack 4
1 parent a0a5c81 commit bd3fb1f

File tree

5 files changed

+127
-26
lines changed

5 files changed

+127
-26
lines changed

package.json

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,18 @@
2424
"lint": "eslint .",
2525
"dev": "esno src/cli.ts",
2626
"build": "tsc",
27-
"test": "jest tests/*.ts"
27+
"test": "jest tests/*.ts && :"
2828
},
2929
"husky": {
3030
"hooks": {
31-
"pre-commit": "lint-staged"
31+
"pre-commit": "npm run build && lint-staged"
3232
}
3333
},
3434
"lint-staged": {
35-
"*.{js,ts}": "eslint"
35+
"*.{js,ts}": [
36+
"eslint",
37+
"npm test"
38+
]
3639
},
3740
"peerDependencies": {
3841
"mocha": "^6.1.4 || ^8.3.2",
@@ -50,6 +53,7 @@
5053
"@pvtnbr/eslint-config-typescript": "^0.1.14",
5154
"@types/mocha": "^8.2.2",
5255
"@types/yargs": "^16.0.1",
56+
"chai": "^4.3.4",
5357
"es-jest": "^1.2.0",
5458
"eslint": "^7.24.0",
5559
"esno": "^0.5.0",
@@ -59,12 +63,14 @@
5963
"lint-staged": "^10.5.4",
6064
"mocha": "^8.3.2",
6165
"typescript": "^4.2.4",
62-
"webpack4": "npm:[email protected]",
63-
"webpack": "^5.35.1"
66+
"webpack": "^5.35.1",
67+
"webpack4": "npm:[email protected]"
6468
},
6569
"eslintConfig": {
6670
"extends": "@pvtnbr/eslint-config-typescript",
67-
"ignorePatterns": ["tests/fixture"],
71+
"ignorePatterns": [
72+
"tests/fixture"
73+
],
6874
"overrides": [
6975
{
7076
"files": "cli.ts",

pnpm-lock.yaml

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib/webpack.ts

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,84 @@
1-
import Module from 'module';
21
import webpack from 'webpack';
32
import AggregateError from 'aggregate-error';
43
import { mfs } from './memfs';
54

5+
const bareSpecifierPattern = /^[^./]/;
6+
7+
const safeResolve = (request: string) => {
8+
try {
9+
return require.resolve(request);
10+
} catch {
11+
return false;
12+
}
13+
};
14+
15+
const isNodeModule = (request: string) => (
16+
bareSpecifierPattern.test(request)
17+
&& safeResolve(request)
18+
);
19+
620
export function createWebpackCompiler(
721
webpackConfig: webpack.Configuration,
822
testFiles: string[],
923
) {
10-
const config = {
11-
...webpackConfig,
24+
const config = { ...webpackConfig };
1225

13-
entry: testFiles,
26+
config.entry = testFiles;
1427

15-
// Yields unexpected behavior in certain loaders
16-
// eg. vue-loader will build in SSR mode
17-
// target: 'node',
28+
config.output = {
29+
...webpackConfig.output,
1830

19-
output: {
20-
...webpackConfig.output,
31+
path: '/',
2132

22-
path: '/',
33+
// https://stackoverflow.com/a/64715069
34+
publicPath: '',
2335

24-
// https://stackoverflow.com/a/64715069
25-
publicPath: '',
36+
// For Node.js env
37+
// https://webpack.js.org/configuration/output/#outputglobalobject
38+
globalObject: 'this',
2639

27-
// For Node.js env
28-
// https://webpack.js.org/configuration/output/#outputglobalobject
29-
globalObject: 'this',
30-
31-
libraryTarget: 'commonjs2',
32-
},
40+
libraryTarget: 'commonjs2',
3341
};
3442

43+
if (!Array.isArray(config.externals)) {
44+
const { externals } = config;
45+
config.externals = [];
46+
47+
if (externals) {
48+
config.externals.push(externals);
49+
}
50+
}
51+
3552
if (webpack.version?.split('.')[0] > '4') {
3653
// Externalize Node built-in modules
3754
if (!config.externalsPresets) {
3855
config.externalsPresets = {};
3956
}
4057
config.externalsPresets.node = true;
4158

59+
// Externalize bare-specifiers that are resolvable by Node.js (aka node_modules)
60+
config.externals.push(({ request }, callback) => {
61+
callback(
62+
null,
63+
isNodeModule(request) ? request : undefined,
64+
);
65+
});
66+
4267
// Same as target: 'node' for async loading chunks
4368
Object.assign(config.output, {
4469
chunkLoading: 'require',
4570
chunkFormat: 'commonjs',
4671
});
4772
} else {
73+
// Externalize bare-specifiers that are resolvable by Node.js (aka node_modules)
74+
// @ts-expect-error WP 4 has different signature
75+
config.externals.push((_, request, callback) => {
76+
callback(
77+
null,
78+
isNodeModule(request) ? request : undefined,
79+
);
80+
});
81+
4882
/**
4983
* Applied when target = 'node'
5084
* https://github.com/webpack/webpack/blob/v4.0.0/lib/WebpackOptionsApply.js#L107
@@ -65,7 +99,7 @@ export function createWebpackCompiler(
6599

66100
const target = config.target ?? 'web';
67101
// @ts-expect-error WP4 accepts functions
68-
config.target = function (compiler) {
102+
config.target = (compiler) => {
69103
// CJS Chunks
70104
new NodeTemplatePlugin().apply(compiler);
71105
new ReadFileCompileWasmTemplatePlugin(config.output).apply(compiler);

tests/fixture/tests/using-chai.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { assert } from 'chai';
2+
import { add } from '~/add';
3+
4+
it('should add', () => {
5+
assert(
6+
add(1, 1) === 2,
7+
'1 + 1 = 2',
8+
);
9+
});

tests/instant-mocha.spec.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import execa from 'execa';
44
const instantMocha = path.resolve('./bin/instant-mocha.js');
55

66
describe.each([
7-
['Webpack 5', []],
7+
// ['Webpack 5', []],
88
['Webpack 4', ['-r', '../use-webpack4.js']],
99
])('%s', (_name, webpackVersion) => {
1010
test('running tests', async () => {
@@ -68,4 +68,19 @@ describe.each([
6868
expect(stdout).toMatch('1 passing');
6969
expect(exitCode).toBe(0);
7070
});
71+
72+
test('custom assertion library - chai', async () => {
73+
const { exitCode, stdout } = await execa('node', [
74+
...webpackVersion,
75+
instantMocha,
76+
'--webpackConfig',
77+
'webpack.config.js',
78+
'tests/using-chai.js',
79+
], {
80+
cwd: path.resolve('tests/fixture'),
81+
}).catch(error => error);
82+
83+
expect(stdout).toMatch('1 passing');
84+
expect(exitCode).toBe(0);
85+
});
7186
});

0 commit comments

Comments
 (0)