Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple entry inputs #410

Merged
merged 11 commits into from
May 28, 2019
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@google-cloud/firestore": "^0.19.0",
"@sentry/node": "^4.3.0",
"@tensorflow/tfjs-node": "^0.3.0",
"@zeit/webpack-asset-relocator-loader": "0.5.0-beta.6",
"@zeit/webpack-asset-relocator-loader": "0.5.1",
"analytics-node": "^3.3.0",
"apollo-server-express": "^2.2.2",
"arg": "^4.1.0",
Expand Down
33 changes: 28 additions & 5 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ $ ncc build input.js -o dist

Outputs the Node.js compact build of `input.js` into `dist/index.js`.

It is also possible to build multiple files in a code-splitting build by passing additional inputs.

### Execution Testing

For testing and debugging, a file can be built into a temporary directory and executed with full source maps support with the command:
Expand Down Expand Up @@ -68,6 +70,8 @@ See [package-support.md](package-support.md) for some common packages and their

```js
require('@zeit/ncc')('/path/to/input', {
// custom filename to use in output (default is "index.js")
filename: 'build.js',
// provide a custom cache path or disable caching
cache: "./custom/cache/path" | false,
// externals to leave as requires of the build
Expand All @@ -82,20 +86,39 @@ require('@zeit/ncc')('/path/to/input', {
v8cache: false, // default
quiet: false, // default
debugLog = false // default
}).then(({ code, map, assets }) => {
console.log(code);
// Assets is an object of asset file names to { source, permissions, symlinks }
// expected relative to the output code (if any)
}).then(({ files, symlinks }) => {
guybedford marked this conversation as resolved.
Show resolved Hide resolved
// files: an object of file names to { source, permissions }
// symlinks: an object of symlink mappings required for the build
styfle marked this conversation as resolved.
Show resolved Hide resolved
// The main build file is located at files[filename]:
files['build.js'].source
})
```

Multiple entry points can be built by providing an object to build. In this case, those files are avaiable as additional output files:

```js
require('@zeit/ncc')({
styfle marked this conversation as resolved.
Show resolved Hide resolved
entry1: '/path/to/input1',
entry2: '/path/to/input2
}, {
filename: '[name].js' // default
}).then(({ files, symlinks }) => {
files['entry1.js'].source
styfle marked this conversation as resolved.
Show resolved Hide resolved
files['entry1.js.map'].source
files['entry2.js'].source
// ... assets
});
```

The `filename` option supports all Webpack supported patterns (eg `[name].js`) in the multi-entry case.

When `watch: true` is set, the build object is not a promise, but has the following signature:

```js
{
// handler re-run on each build completion
// watch errors are reported on "err"
handler (({ err, code, map, assets }) => { ... })
handler (({ err, files, symlinks }) => { ... })
// handler re-run on each rebuild start
rebuild (() => {})
// close the watcher
Expand Down
70 changes: 37 additions & 33 deletions scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,27 @@ const copy = promisify(require("copy"));
const glob = promisify(require("glob"));
const bytes = require("bytes");

function assetList (files) {
return Object.keys(files).filter(file => file.startsWith('assets/')).map(file => file.substr(7));
}

async function main() {
for (const file of await glob(__dirname + "/../dist/**/*.@(js|cache|ts)")) {
unlinkSync(file);
}

const { code: cli, assets: cliAssets } = await ncc(
const { files: cliFiles } = await ncc(
__dirname + "/../src/cli",
{
filename: "cli.js",
externals: ["./index.js"],
filename: "cli.js",
minify: true,
v8cache: true
}
);
checkUnknownAssets('cli', Object.keys(cliAssets));
checkUnknownAssets('cli', assetList(cliFiles));

const { code: index, assets: indexAssets } = await ncc(
const { files: indexFiles } = await ncc(
__dirname + "/../src/index",
{
// we dont care about watching, so we don't want
Expand All @@ -35,35 +39,35 @@ async function main() {
v8cache: true
}
);
checkUnknownAssets('index', Object.keys(indexAssets).filter(asset => !asset.startsWith('locales/') && asset !== 'worker.js' && asset !== 'index1.js'));
checkUnknownAssets('index', assetList(indexFiles).filter(asset => !asset.startsWith('locales/') && asset !== 'worker.js' && asset !== 'index.js'));

const { code: relocateLoader, assets: relocateLoaderAssets } = await ncc(
const { files: relocateLoaderFiles } = await ncc(
__dirname + "/../src/loaders/relocate-loader",
{ filename: "relocate-loader.js", minify: true, v8cache: true }
);
checkUnknownAssets('relocate-loader', Object.keys(relocateLoaderAssets));
checkUnknownAssets('relocate-loader', assetList(relocateLoaderFiles));

const { code: shebangLoader, assets: shebangLoaderAssets } = await ncc(
const { files: shebangLoaderFiles } = await ncc(
__dirname + "/../src/loaders/shebang-loader",
{ filename: "shebang-loader.js", minify: true, v8cache: true }
);
checkUnknownAssets('shebang-loader', Object.keys(shebangLoaderAssets));
checkUnknownAssets('shebang-loader', assetList(shebangLoaderFiles));

const { code: tsLoader, assets: tsLoaderAssets } = await ncc(
const { files: tsLoaderFiles } = await ncc(
__dirname + "/../src/loaders/ts-loader",
{
filename: "ts-loader.js",
minify: true,
v8cache: true
}
);
checkUnknownAssets('ts-loader', Object.keys(tsLoaderAssets).filter(asset => !asset.startsWith('lib/') && !asset.startsWith('typescript/lib')));
checkUnknownAssets('ts-loader', assetList(tsLoaderFiles).filter(asset => !asset.startsWith('lib/') && !asset.startsWith('typescript/lib')));

const { code: sourcemapSupport, assets: sourcemapAssets } = await ncc(
const { files: sourceMapSupportFiles } = await ncc(
require.resolve("source-map-support/register"),
{ filename: "sourcemap-register.js", minfiy: true, v8cache: true }
);
checkUnknownAssets('source-map-support/register', Object.keys(sourcemapAssets));
checkUnknownAssets('source-map-support/register', assetList(sourceMapSupportFiles));

// detect unexpected asset emissions from core build
function checkUnknownAssets (buildName, assets) {
Expand All @@ -73,22 +77,22 @@ async function main() {
console.log(assets);
}

writeFileSync(__dirname + "/../dist/ncc/cli.js.cache", cliAssets["cli.js.cache"].source);
writeFileSync(__dirname + "/../dist/ncc/index.js.cache", indexAssets["index.js.cache"].source);
writeFileSync(__dirname + "/../dist/ncc/sourcemap-register.js.cache", sourcemapAssets["sourcemap-register.js.cache"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/relocate-loader.js.cache", relocateLoaderAssets["relocate-loader.js.cache"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/shebang-loader.js.cache", shebangLoaderAssets["shebang-loader.js.cache"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/ts-loader.js.cache", tsLoaderAssets["ts-loader.js.cache"].source);

writeFileSync(__dirname + "/../dist/ncc/cli.js.cache.js", cliAssets["cli.js.cache.js"].source);
writeFileSync(__dirname + "/../dist/ncc/index.js.cache.js", indexAssets["index.js.cache.js"].source);
writeFileSync(__dirname + "/../dist/ncc/sourcemap-register.js.cache.js", sourcemapAssets["sourcemap-register.js.cache.js"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/relocate-loader.js.cache.js", relocateLoaderAssets["relocate-loader.js.cache.js"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/shebang-loader.js.cache.js", shebangLoaderAssets["shebang-loader.js.cache.js"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/ts-loader.js.cache.js", tsLoaderAssets["ts-loader.js.cache.js"].source);

writeFileSync(__dirname + "/../dist/ncc/cli.js", cli, { mode: 0o777 });
writeFileSync(__dirname + "/../dist/ncc/index.js", index);
writeFileSync(__dirname + "/../dist/ncc/cli.js.cache", cliFiles["cli.js.cache"].source);
writeFileSync(__dirname + "/../dist/ncc/index.js.cache", indexFiles["index.js.cache"].source);
writeFileSync(__dirname + "/../dist/ncc/sourcemap-register.js.cache", sourceMapSupportFiles["sourcemap-register.js.cache"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/relocate-loader.js.cache", relocateLoaderFiles["relocate-loader.js.cache"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/shebang-loader.js.cache", shebangLoaderFiles["shebang-loader.js.cache"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/ts-loader.js.cache", tsLoaderFiles["ts-loader.js.cache"].source);

writeFileSync(__dirname + "/../dist/ncc/cli.js.cache.js", cliFiles["cli.js.cache.js"].source);
writeFileSync(__dirname + "/../dist/ncc/index.js.cache.js", indexFiles["index.js.cache.js"].source);
writeFileSync(__dirname + "/../dist/ncc/sourcemap-register.js.cache.js", sourceMapSupportFiles["sourcemap-register.js.cache.js"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/relocate-loader.js.cache.js", relocateLoaderFiles["relocate-loader.js.cache.js"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/shebang-loader.js.cache.js", shebangLoaderFiles["shebang-loader.js.cache.js"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/ts-loader.js.cache.js", tsLoaderFiles["ts-loader.js.cache.js"].source);

writeFileSync(__dirname + "/../dist/ncc/cli.js", cliFiles["cli.js"].source, { mode: 0o777 });
writeFileSync(__dirname + "/../dist/ncc/index.js", indexFiles["index.js"].source);
writeFileSync(__dirname + "/../dist/ncc/typescript.js", `
const { Module } = require('module');
const m = new Module('', null);
Expand All @@ -104,10 +108,10 @@ catch (e) {
}
module.exports = typescript;
`);
writeFileSync(__dirname + "/../dist/ncc/sourcemap-register.js", sourcemapSupport);
writeFileSync(__dirname + "/../dist/ncc/loaders/relocate-loader.js", relocateLoader);
writeFileSync(__dirname + "/../dist/ncc/loaders/shebang-loader.js", shebangLoader);
writeFileSync(__dirname + "/../dist/ncc/loaders/ts-loader.js", tsLoader);
writeFileSync(__dirname + "/../dist/ncc/sourcemap-register.js", sourceMapSupportFiles["sourcemap-register.js"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/relocate-loader.js", relocateLoaderFiles["relocate-loader.js"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/shebang-loader.js", shebangLoaderFiles["shebang-loader.js"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/ts-loader.js", tsLoaderFiles["ts-loader.js"].source);
writeFileSync(__dirname + "/../dist/ncc/loaders/uncacheable.js", readFileSync(__dirname + "/../src/loaders/uncacheable.js"));
writeFileSync(__dirname + "/../dist/ncc/loaders/empty-loader.js", readFileSync(__dirname + "/../src/loaders/empty-loader.js"));
writeFileSync(__dirname + "/../dist/ncc/loaders/notfound-loader.js", readFileSync(__dirname + "/../src/loaders/notfound-loader.js"));
Expand Down
Loading