Skip to content

Commit

Permalink
Use Rollup to reduce the npm package to just 3 JS files (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
lydell authored Jun 12, 2021
1 parent 3fc1659 commit c755e36
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 34 deletions.
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ module.exports = {
// Testing error handling is still manual, though.
// We still get 40-50% coverage at least.
"./src/commands/Install.ts": ignoreCoverage,
"./src/RollupEntry.ts": ignoreCoverage,
},
};
42 changes: 42 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"build": "ts-node scripts/Build.ts"
},
"devDependencies": {
"@rollup/plugin-typescript": "8.2.1",
"@types/jest": "26.0.23",
"@types/node": "15.12.2",
"@types/rimraf": "3.0.0",
Expand All @@ -19,6 +20,7 @@
"jest": "27.0.4",
"prettier": "2.3.1",
"rimraf": "3.0.2",
"rollup": "2.51.2",
"ts-jest": "27.0.3",
"ts-node": "10.0.0",
"typescript": "4.3.2"
Expand Down
89 changes: 61 additions & 28 deletions scripts/Build.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import * as childProcess from "child_process";
import typescript from "@rollup/plugin-typescript";
import * as fs from "fs";
import { builtinModules } from "module";
import * as path from "path";
import * as rimraf from "rimraf";
import { rollup } from "rollup";

const DIR = path.dirname(__dirname);
const BUILD = path.join(DIR, "build");
Expand Down Expand Up @@ -29,40 +31,71 @@ const FILES_TO_COPY: Array<FileToCopy> = [
{ src: "README-npm.md", dest: "README.md" },
];

if (fs.existsSync(BUILD)) {
rimraf.sync(BUILD);
}

fs.mkdirSync(BUILD);

for (const { src, dest = src } of FILES_TO_COPY) {
fs.copyFileSync(path.join(DIR, src), path.join(BUILD, dest));
}

childProcess.spawnSync("npx", ["--no-install", "tsc"], {
shell: true,
stdio: "inherit",
});

function modifyFile(
file: string,
transform: (content: string) => string
): void {
fs.writeFileSync(file, transform(fs.readFileSync(file, "utf8")));
}

function adjustDefaultExport(content: string): string {
return content.replace(/^exports.default =/m, "module.exports =");
}
async function run(): Promise<void> {
if (fs.existsSync(BUILD)) {
rimraf.sync(BUILD);
}

modifyFile(path.join(BUILD, "index.js"), adjustDefaultExport);
modifyFile(path.join(BUILD, "getExecutable.js"), adjustDefaultExport);
modifyFile(path.join(BUILD, "commands", "Help.js"), (content) =>
content.replace(/%VERSION%/g, PKG.version)
);
fs.mkdirSync(BUILD);

fs.chmodSync(path.join(BUILD, "index.js"), "755");
for (const { src, dest = src } of FILES_TO_COPY) {
fs.copyFileSync(path.join(DIR, src), path.join(BUILD, dest));
}

modifyFile(path.join(DIR, "docs", "getting-started.md"), (content) =>
content.replace(/("elm-tooling":\s*)"[^"]+"/g, `$1"${PKG.version}"`)
);
const entry = path.join(DIR, "src", "RollupEntry.ts");

const bundle = await rollup({
input: entry,
external: builtinModules,
plugins: [typescript()],
onwarn: (warning) => {
// Rollup warnings _do_ have a real `.toString()` method.
// eslint-disable-next-line @typescript-eslint/no-base-to-string
throw new Error(warning.toString());
},
});

const { output } = await bundle.generate({
format: "cjs",
hoistTransitiveImports: false,
chunkFileNames: "[name].js",
interop: "esModule",
});

for (const item of output) {
switch (item.type) {
case "asset":
throw new Error(`Unexpectedly got an "asset".`);

case "chunk":
if (item.facadeModuleId !== entry) {
const isIndex = item.name === "index";
const code = item.code
.replace(/%VERSION%/g, PKG.version)
.replace(/^exports.default =/m, "module.exports =");
const fullCode = isIndex ? `#!/usr/bin/env node\n${code}` : code;
fs.writeFileSync(
path.join(BUILD, item.fileName),
fullCode,
isIndex ? { mode: "755" } : {}
);
}
}
}

modifyFile(path.join(DIR, "docs", "getting-started.md"), (content) =>
content.replace(/("elm-tooling":\s*)"[^"]+"/g, `$1"${PKG.version}"`)
);
}

run().catch((error: Error) => {
process.stderr.write(`${error.message}\n`);
process.exit(1);
});
3 changes: 2 additions & 1 deletion scripts/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"extends": "../tsconfig.json",
"exclude": [],
"compilerOptions": {
"noEmit": true
"esModuleInterop": true,
"module": "CommonJS",
}
}
12 changes: 12 additions & 0 deletions src/RollupEntry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */

// This file is only used to get Rollup to output the files we want: One file
// per entrypoint, and one shared file.

export async function index() {
return import("./index");
}

export async function getExecutable() {
return import("./getExecutable");
}
2 changes: 0 additions & 2 deletions src/index.ts
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env node

import { help } from "./commands/Help";
import { init } from "./commands/Init";
import { install } from "./commands/Install";
Expand Down
2 changes: 1 addition & 1 deletion tests/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"extends": "../tsconfig.json",
"exclude": [],
"compilerOptions": {
"noEmit": true
"module": "CommonJS",
}
}
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
"forceConsistentCasingInFileNames": true,
"importsNotUsedAsValues": "error",
"isolatedModules": true,
"module": "CommonJS",
"module": "ESNext",
"moduleResolution": "node",
"noEmit": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
Expand All @@ -18,7 +19,6 @@
"lib": [
"ES2018",
],
"outDir": "build"
},
"exclude": [
"scripts",
Expand Down

0 comments on commit c755e36

Please sign in to comment.