Skip to content

Commit 09dc40d

Browse files
committed
Merge branch 'master' of github.com:zeit/ncc
2 parents f5d6475 + 208cdc0 commit 09dc40d

File tree

29 files changed

+221
-335
lines changed

29 files changed

+221
-335
lines changed

dist/ncc/typescript/readme.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# About this directory
2+
3+
This directory will contain:
4+
5+
- `index.js` the TypeScript entry point
6+
- `typescript.js` the local NCC TypeScript build to use when no local version is available
7+
8+
These are generated by the `build` step defined in `../../package.json`.
9+
10+
These files are published to npm.

scripts/build.js

+22-6
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ async function main() {
2828

2929
const { code: nodeLoader, assets: nodeLoaderAssets } = await ncc(
3030
__dirname + "/../src/loaders/node-loader",
31-
{
32-
minify: true
33-
}
31+
{ minify: true }
3432
);
3533

3634
const { code: relocateLoader, assets: relocateLoaderAssets } = await ncc(
@@ -45,30 +43,48 @@ async function main() {
4543

4644
const { code: tsLoader, assets: tsLoaderAssets } = await ncc(
4745
__dirname + "/../src/loaders/ts-loader",
48-
{ minify: true }
46+
{
47+
externals: ["typescript"],
48+
minify: true
49+
}
4950
);
5051

5152
const { code: sourcemapSupport, assets: sourcemapAssets } = await ncc(
5253
require.resolve("source-map-support/register"),
5354
{ minfiy: true }
5455
);
5556

57+
const { code: typescript, assets: typescriptAssets } = await ncc(
58+
"typescript",
59+
{ minify: true }
60+
);
61+
5662
// detect unexpected asset emissions from core build
5763
if (
5864
Object.keys(cliAssets).length ||
5965
Object.keys(indexAssets).some(asset => !asset.startsWith('locales/')) ||
6066
Object.keys(nodeLoaderAssets).length ||
6167
Object.keys(relocateLoaderAssets).length ||
6268
Object.keys(shebangLoaderAssets).length ||
63-
Object.keys(tsLoaderAssets).some(asset => !asset.startsWith('lib/')) ||
64-
Object.keys(sourcemapAssets).length
69+
Object.keys(tsLoaderAssets).length ||
70+
Object.keys(sourcemapAssets).length ||
71+
Object.keys(typescriptAssets).some(asset => !asset.startsWith('lib/'))
6572
) {
6673
console.error("New assets are being emitted by the core build");
6774
}
6875

6976
writeFileSync(__dirname + "/../dist/ncc/cli.js", cli);
7077
writeFileSync(__dirname + "/../dist/ncc/index.js", index);
78+
writeFileSync(__dirname + "/../dist/ncc/typescript/index.js", `
79+
try {
80+
module.exports = require('typescript');
81+
}
82+
catch (e) {
83+
module.exports = require('./typescript.js');
84+
}
85+
`);
7186
writeFileSync(__dirname + "/../dist/ncc/sourcemap-register.js", sourcemapSupport);
87+
writeFileSync(__dirname + "/../dist/ncc/typescript/typescript.js", typescript);
7288
writeFileSync(__dirname + "/../dist/ncc/loaders/node-loader.js", nodeLoader);
7389
writeFileSync(__dirname + "/../dist/ncc/loaders/relocate-loader.js", relocateLoader);
7490
writeFileSync(__dirname + "/../dist/ncc/loaders/shebang-loader.js", shebangLoader);

src/index.js

+11-37
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const resolve = require("resolve");
22
const fs = require("graceful-fs");
33
const crypto = require("crypto");
4-
const { dirname, sep } = require("path");
4+
const { sep, dirname } = require("path");
55
const webpack = require("webpack");
66
const MemoryFS = require("memory-fs");
77
const terser = require("terser");
@@ -11,6 +11,9 @@ const shebangRegEx = require('./utils/shebang');
1111
const { pkgNameRegEx } = require("./utils/get-package-base");
1212
const nccCacheDir = require("./utils/ncc-cache-dir");
1313

14+
// support glob graceful-fs
15+
fs.gracefulify(require("fs"));
16+
1417
const nodeBuiltins = new Set([...require("repl")._builtinLibs, "constants", "module", "timers", "console", "_stream_writable", "_stream_readable", "_stream_duplex"]);
1518

1619
const SUPPORTED_EXTENSIONS = [".js", ".json", ".node", ".mjs", ".ts", ".tsx"];
@@ -126,24 +129,25 @@ module.exports = (
126129
{
127130
test: /\.node$/,
128131
use: [{
129-
loader: __dirname + "/loaders/node-loader.js"
132+
loader: eval('__dirname + "/loaders/node-loader.js"')
130133
}]
131134
},
132135
{
133136
test: /\.(js|mjs|tsx?)$/,
134137
use: [{
135-
loader: __dirname + "/loaders/relocate-loader.js",
138+
loader: eval('__dirname + "/loaders/relocate-loader.js"'),
136139
options: { cwd: dirname(resolvedEntry) }
137140
}]
138141
},
139142
{
140143
test: /\.tsx?$/,
141144
use: [{
142-
loader: __dirname + "/loaders/uncacheable.js"
143-
},
145+
loader: eval('__dirname + "/loaders/uncacheable.js"')
146+
},
144147
{
145-
loader: __dirname + "/loaders/ts-loader.js",
148+
loader: eval('__dirname + "/loaders/ts-loader.js"'),
146149
options: {
150+
compiler: eval('__dirname + "/typescript"'),
147151
compilerOptions: {
148152
outDir: '//'
149153
}
@@ -154,7 +158,7 @@ module.exports = (
154158
parser: { amd: false },
155159
exclude: /\.node$/,
156160
use: [{
157-
loader: __dirname + "/loaders/shebang-loader.js"
161+
loader: eval('__dirname + "/loaders/shebang-loader.js"')
158162
}]
159163
}
160164
]
@@ -178,36 +182,6 @@ module.exports = (
178182
if (err) console.error(err);
179183
assetState.assetPermissions = JSON.parse(_assetPermissions || 'null') || Object.create(null);
180184
}); */
181-
// hack to ensure __webpack_require__ is added to empty context wrapper
182-
compilation.hooks.additionalModuleRuntimeRequirements.tap("ncc", (module, runtimeRequirements) => {
183-
if(module._contextDependencies)
184-
runtimeRequirements.add('__webpack_require__');
185-
});
186-
compilation.moduleTemplates.javascript.hooks.render.tap(
187-
"ncc",
188-
(
189-
moduleSourcePostModule,
190-
module,
191-
options,
192-
dependencyTemplates
193-
) => {
194-
if (
195-
module._contextDependencies &&
196-
moduleSourcePostModule._value.match(
197-
/webpackEmptyAsyncContext|webpackEmptyContext/
198-
)
199-
) {
200-
return moduleSourcePostModule._value.replace(
201-
"var e = new Error",
202-
`if (typeof req === 'number')\n` +
203-
` return __webpack_require__(req);\n` +
204-
`try { return require(req) }\n` +
205-
`catch (e) { if (e.code !== 'MODULE_NOT_FOUND') throw e }\n` +
206-
`var e = new Error`
207-
);
208-
}
209-
}
210-
);
211185
});
212186

213187
compiler.hooks.normalModuleFactory.tap("ncc", NormalModuleFactory => {

src/loaders/relocate-loader.js

+22-25
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const getUniqueAssetName = require('../utils/dedupe-names');
1010
const sharedlibEmit = require('../utils/sharedlib-emit');
1111
const glob = require('glob');
1212
const getPackageBase = require('../utils/get-package-base');
13-
const { getOptions } = require('loader-utils');
1413

1514
// binary support for inlining logic from - node-pre-gyp/lib/pre-binding.js
1615
function isPregypId (id) {
@@ -114,9 +113,6 @@ function isExpressionReference(node, parent) {
114113
// disregard the `bar` in var bar = asdf
115114
if (parent.type === 'VariableDeclarator' && node.id === node) return false;
116115

117-
// disregard the `x` in import/export 'x';
118-
if (parent.type === 'ImportDeclaration' || parent.type === 'ExportNamedDeclaration' || parent.type === 'ExportAllDeclaration') return false;
119-
120116
return true;
121117
}
122118

@@ -275,14 +271,13 @@ function handleWrappers (ast, scope, magicString, len) {
275271
return { ast, scope, transformed };
276272
}
277273

278-
const relocateRegEx = /_\_dirname|_\_filename|require\.main|node-pre-gyp|bindings|define|['"]\.\.?\//;
274+
const relocateRegEx = /_\_dirname|_\_filename|require\.main|node-pre-gyp|bindings|define|require\(\s*[^'"]/;
279275

280276
module.exports = function (code) {
281277
if (this.cacheable)
282278
this.cacheable();
283279
this.async();
284280
const id = this.resourcePath;
285-
const { cwd } = getOptions(this);
286281

287282
if (id.endsWith('.json') || !code.match(relocateRegEx))
288283
return this.callback(null, code);
@@ -497,8 +492,8 @@ module.exports = function (code) {
497492
node.arguments[0].type === 'Literal';
498493
}
499494

500-
// detect require(...) || require.resolve(...);
501-
function isRequire (node) {
495+
// detect require(...)
496+
function isRequire (node, requireResolve) {
502497
return node &&
503498
node.type === 'CallExpression' &&
504499
(node.callee.type === 'Identifier' &&
@@ -507,8 +502,16 @@ module.exports = function (code) {
507502
node.callee.type === 'MemberExpression' &&
508503
node.callee.object.type === 'Identifier' &&
509504
node.callee.object.name === 'require' &&
505+
(!requireResolve ||
510506
node.callee.property.type === 'Identifier' &&
511-
node.callee.property.name === 'resolve');
507+
node.callee.property.name === 'resolve'));
508+
}
509+
510+
function isAnalyzableRequire (expression) {
511+
if (expression.type === 'Identifier' || expression.type === 'MemberExpression')
512+
return false;
513+
// "possibly" analyzable (this can be further restricted over time)
514+
return true;
512515
}
513516

514517
({ ast, scope, transformed } = handleWrappers(ast, scope, magicString, code.length));
@@ -543,18 +546,9 @@ module.exports = function (code) {
543546
}
544547
}
545548
}
546-
// special trigger for './asset.txt' references
547-
else if (node.type === 'Literal' && typeof node.value === 'string' &&
548-
(node.value.startsWith('./') || node.value.startsWith('../')) &&
549-
isExpressionReference(node, parent)) {
550-
staticChildValue = node.value;
551-
staticChildNode = node;
552-
staticChildValueBindingsInstance = staticBindingsInstance;
553-
return this.skip();
554-
}
555549
// require('bindings')('asdf')
556-
else if (node.type === 'CallExpression' &&
557-
!isESM && isStaticRequire(node.callee) &&
550+
else if (node.type === 'CallExpression' && !isESM &&
551+
isStaticRequire(node.callee) &&
558552
node.callee.arguments[0].value === 'bindings') {
559553
staticChildValue = computeStaticValue(node, true);
560554
if (staticChildValue) {
@@ -563,6 +557,12 @@ module.exports = function (code) {
563557
return this.skip();
564558
}
565559
}
560+
// require(dynamic) -> __non_webpack_require__(dynamic)
561+
else if (isRequire(node) && !isAnalyzableRequire(node.arguments[0])) {
562+
transformed = true;
563+
magicString.overwrite(node.callee.start, node.callee.end, "__non_webpack_require__");
564+
return this.skip();
565+
}
566566
// nbind.init(...) -> require('./resolved.node')
567567
else if (nbindId && node.type === 'CallExpression' &&
568568
node.callee.type === 'MemberExpression' &&
@@ -701,12 +701,9 @@ module.exports = function (code) {
701701
return;
702702
}
703703
// no static value -> see if we should emit the asset if it exists
704-
// never inline an asset path into a require statement though
704+
// Currently we only handle files. In theory whole directories could also be emitted if necessary.
705705
let stats;
706-
if (typeof staticChildValue === 'string' && !isRequire(node)) {
707-
if (staticChildValue.startsWith('./') || staticChildValue.startsWith('../')) {
708-
staticChildValue = path.resolve(cwd, staticChildValue);
709-
}
706+
if (typeof staticChildValue === 'string') {
710707
try {
711708
stats = fs.statSync(staticChildValue);
712709
}

src/typescript/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('typescript');

test/index.test.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const fs = require("fs");
2-
const ncc = global.coverage ? require("../src/index") : require("../src");
2+
const ncc = global.coverage ? require("../src/index") : require("../");
33
const mkdirp = require("mkdirp");
44
const rimraf = require("rimraf");
55
const { dirname } = require("path");
@@ -20,11 +20,6 @@ for (const unitTest of fs.readdirSync(`${__dirname}/unit`)) {
2020
const inputFile = fs.readdirSync(testDir).find(file => file.includes("input"));
2121
await ncc(`${testDir}/${inputFile}`).then(
2222
async ({ code, assets }) => {
23-
// very simple asset validation in unit tests
24-
if (unitTest.startsWith("asset-")) {
25-
expect(Object.keys(assets).length).toBeGreaterThan(0);
26-
expect(assets[Object.keys(assets)[0].source] instanceof Buffer);
27-
}
2823
const actual = code
2924
.trim()
3025
// Windows support
@@ -36,6 +31,12 @@ for (const unitTest of fs.readdirSync(`${__dirname}/unit`)) {
3631
fs.writeFileSync(`${testDir}/actual.js`, actual);
3732
throw e;
3833
}
34+
35+
// very simple asset validation in unit tests
36+
if (unitTest.startsWith("asset-")) {
37+
expect(Object.keys(assets).length).toBeGreaterThan(0);
38+
expect(assets[Object.keys(assets)[0].source] instanceof Buffer);
39+
}
3940
}
4041
);
4142
});

test/unit/amd-disable/output.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ module.exports =
3232
/******/
3333
/******/
3434
/******/ // Load entry module and return exports
35-
/******/ return __webpack_require__(901);
35+
/******/ return __webpack_require__(947);
3636
/******/ })
3737
/************************************************************************/
3838
/******/ ({
3939

40-
/***/ 901:
40+
/***/ 947:
4141
/***/ (function() {
4242

4343
if (typeof define === 'function' && define.amd)

test/unit/asset-fs-inline-path-enc-es-2/output.js

+16-16
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,12 @@ module.exports =
3434
/******/ runtime(__webpack_require__);
3535
/******/
3636
/******/ // Load entry module and return exports
37-
/******/ return __webpack_require__(954);
37+
/******/ return __webpack_require__(259);
3838
/******/ })
3939
/************************************************************************/
4040
/******/ ({
4141

42-
/***/ 589:
43-
/***/ (function(module) {
44-
45-
module.exports = require("path");
46-
47-
/***/ }),
48-
49-
/***/ 66:
50-
/***/ (function(module) {
51-
52-
module.exports = require("fs");
53-
54-
/***/ }),
55-
56-
/***/ 954:
42+
/***/ 259:
5743
/***/ (function(__unusedmodule, __webpack_exports__, __webpack_require__) {
5844

5945
"use strict";
@@ -67,6 +53,20 @@ __webpack_require__.r(__webpack_exports__);
6753

6854
console.log(fs__WEBPACK_IMPORTED_MODULE_0___default.a.readFileSync(__dirname + '/asset.txt', 'utf8'));
6955

56+
/***/ }),
57+
58+
/***/ 589:
59+
/***/ (function(module) {
60+
61+
module.exports = require("path");
62+
63+
/***/ }),
64+
65+
/***/ 66:
66+
/***/ (function(module) {
67+
68+
module.exports = require("fs");
69+
7070
/***/ })
7171

7272
/******/ },

0 commit comments

Comments
 (0)