Skip to content

Commit

Permalink
Bundle standalone using rollup (#10779)
Browse files Browse the repository at this point in the history
* chore: bundle babel-standalone via rollup

Co-authored-by: Daniel Tschinder <daniel.tschinder@researchgate.net>

* chore: build babel-preset-env-standalone via Rollup

# Conflicts:
#	yarn.lock

* chore: add babelEnvName

* chore: farewell webpack

* chore: add terser minification

* chore: dedupe some popular dependencies

* chore: remove unused devDependencies

* chore: move plugin-babel-source to scripts/

* make prettier happy

* fix: rewrite available-plugins into esm

* chore: add extra unambiguous sources when env is rollup/standalone
  • Loading branch information
JLHwung committed Dec 5, 2019
1 parent 2b47291 commit a0bed42
Show file tree
Hide file tree
Showing 7 changed files with 703 additions and 1,103 deletions.
264 changes: 196 additions & 68 deletions Gulpfile.js
Expand Up @@ -10,12 +10,17 @@ const fancyLog = require("fancy-log");
const filter = require("gulp-filter");
const gulp = require("gulp");
const path = require("path");
const webpack = require("webpack");
const rollup = require("rollup");
const rollupAlias = require("@rollup/plugin-alias");
const rollupBabel = require("rollup-plugin-babel");
const rollupBabelSource = require("./scripts/rollup-plugin-babel-source");
const rollupCommonJs = require("rollup-plugin-commonjs");
const rollupJson = require("@rollup/plugin-json");
const rollupNodeBuiltins = require("rollup-plugin-node-builtins");
const rollupNodeGlobals = require("rollup-plugin-node-globals");
const rollupNodeResolve = require("rollup-plugin-node-resolve");
const rollupReplace = require("rollup-plugin-replace");
const { registerStandalonePackageTask } = require("./scripts/gulp-tasks");
const { terser: rollupTerser } = require("rollup-plugin-terser");

const defaultSourcesGlob = "./@(codemods|packages|eslint)/*/src/**/*.js";

Expand Down Expand Up @@ -75,42 +80,203 @@ function buildBabel(exclude, sourcesGlob = defaultSourcesGlob) {
.pipe(gulp.dest(base));
}

let babelVersion = require("./packages/babel-core/package.json").version;
function buildRollup(packages) {
const sourcemap = process.env.NODE_ENV === "production";
const minify = !!process.env.IS_PUBLISH;
return Promise.all(
packages.map(pkg => {
const input = getIndexFromPackage(pkg);
fancyLog(`Compiling '${chalk.cyan(input)}' with rollup ...`);
return rollup
.rollup({
input,
plugins: [
rollupReplace({
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
}),
rollupBabel({
envName: "babel-parser",
}),
rollupNodeResolve(),
],
})
.then(bundle => {
return bundle.write({
file: path.join(pkg, "lib/index.js"),
format: "cjs",
name: "babel-parser",
sourcemap: process.env.NODE_ENV !== "production",
packages.map(
({ src, format, dest, name, filename, version = babelVersion }) => {
const extraPlugins = [];
let inputExternal = undefined,
outputGlobals = undefined,
nodeResolveBrowser = false,
babelEnvName = "rollup";
switch (src) {
case "packages/babel-standalone":
nodeResolveBrowser = true;
babelEnvName = "standalone";
if (minify) {
extraPlugins.push(
rollupTerser({
include: /^.+\.min\.js$/,
})
);
}
break;
case "packages/babel-preset-env-standalone":
nodeResolveBrowser = true;
babelEnvName = "standalone";
if (minify) {
extraPlugins.push(
rollupTerser({
include: /^.+\.min\.js$/,
})
);
}
inputExternal = ["@babel/standalone"];
outputGlobals = {
"@babel/standalone": "Babel",
};
extraPlugins.push(
rollupAlias({
entries: [
{
find: "./available-plugins",
replacement: require.resolve(
path.join(__dirname, src, "./src/available-plugins")
),
},
{
find: "caniuse-lite/data/regions",
replacement: require.resolve(
path.join(__dirname, src, "./src/caniuse-lite-regions")
),
},
],
})
);
break;
}
// If this build is part of a pull request, include the pull request number in
// the version number.
if (process.env.CIRCLE_PR_NUMBER) {
const prVersion = "+pr." + process.env.CIRCLE_PR_NUMBER;
babelVersion += prVersion;
version += prVersion;
}
const input = getIndexFromPackage(src);
fancyLog(`Compiling '${chalk.cyan(input)}' with rollup ...`);
return rollup
.rollup({
input,
external: inputExternal,
plugins: [
...extraPlugins,
rollupBabelSource(),
rollupReplace({
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
BABEL_VERSION: JSON.stringify(babelVersion),
VERSION: JSON.stringify(version),
}),
rollupBabel({
envName: babelEnvName,
babelrc: false,
extends: "./babel.config.js",
}),
rollupNodeResolve({
browser: nodeResolveBrowser,
preferBuiltins: true,
//todo: When Yarn workspaces is enabled, remove `dedupe` option
dedupe(importee) {
return (
importee.startsWith("lodash/") ||
[
"babel-plugin-dynamic-import-node/utils",
"esutils",
"semver",
"source-map",
].includes(importee)
);
},
}),
rollupCommonJs({
include: [/node_modules/, "packages/babel-preset-env/data/**"],
namedExports: {
"babel-plugin-dynamic-import-node/utils.js": [
"createDynamicImportTransform",
"getImportSource",
],
"@babel/standalone": ["availablePlugins", "registerPlugin"],
},
}),
rollupJson(),
rollupNodeBuiltins(),
rollupNodeGlobals({ sourceMap: sourcemap }),
],
})
.then(bundle => {
const outputFile = path.resolve(src, dest, filename || "index.js");
return bundle
.write({
file: outputFile,
format,
name,
globals: outputGlobals,
sourcemap: sourcemap,
})
.then(() => {
if (!process.env.IS_PUBLISH) {
fancyLog(
chalk.yellow(
`Skipped minification of '${chalk.cyan(
path.relative(path.join(__dirname, ".."), outputFile)
)}' because not publishing`
)
);
return undefined;
}
fancyLog(
`Minifying '${chalk.cyan(
path.relative(path.join(__dirname, ".."), outputFile)
)}'...`
);

return bundle.write({
file: outputFile.replace(/\.js$/, ".min.js"),
format,
name,
globals: outputGlobals,
sourcemap: sourcemap,
});
});
});
});
})
}
)
);
}

const bundles = ["packages/babel-parser"];
const libBundles = [
{
src: "packages/babel-parser",
format: "cjs",
dest: "lib",
version: require("./packages/babel-parser/package").version,
},
];

const standaloneBundle = [
{
src: "packages/babel-standalone",
format: "umd",
name: "Babel",
filename: "babel.js",
dest: "",
version: require("./packages/babel-core/package").version,
},
];

const presetEnvStandaloneBundle = [
{
src: "packages/babel-preset-env-standalone",
format: "umd",
name: "BabelPresetEnv",
filename: "babel-preset-env.js",
dest: "",
version: require("./packages/babel-preset-env/package").version,
},
];

gulp.task("build-rollup", () => buildRollup(libBundles));
gulp.task("build-babel-standalone", () => buildRollup(standaloneBundle));

gulp.task("build-babel-preset-env-standalone", () =>
buildRollup(presetEnvStandaloneBundle)
);

gulp.task("build-rollup", () => buildRollup(bundles));
gulp.task("build-babel", () => buildBabel(/* exclude */ bundles));
gulp.task("build-babel", () => buildBabel(/* exclude */ libBundles));
gulp.task("build-babel-types", () =>
buildBabel(/* exclude */ bundles, "packages/babel-types/src/**/*.js")
buildBabel(/* exclude */ libBundles, "packages/babel-types/src/**/*.js")
);
gulp.task("build", gulp.parallel("build-rollup", "build-babel"));

Expand All @@ -128,41 +294,3 @@ gulp.task(
);
})
);

registerStandalonePackageTask(
gulp,
"babel",
"Babel",
path.join(__dirname, "packages"),
require("./packages/babel-standalone/package.json").version
);

const presetEnvWebpackPlugins = [
new webpack.NormalModuleReplacementPlugin(
/\.\/available-plugins/,
require.resolve(
path.join(
__dirname,
"./packages/babel-preset-env-standalone/src/available-plugins"
)
)
),
new webpack.NormalModuleReplacementPlugin(
/caniuse-lite\/data\/regions\/.+/,
require.resolve(
path.join(
__dirname,
"./packages/babel-preset-env-standalone/src/caniuse-lite-regions"
)
)
),
];

registerStandalonePackageTask(
gulp,
"babel-preset-env",
"babelPresetEnv",
path.join(__dirname, "packages"),
require("./packages/babel-preset-env-standalone/package.json").version,
presetEnvWebpackPlugins
);
62 changes: 24 additions & 38 deletions babel.config.js
Expand Up @@ -11,26 +11,45 @@ module.exports = function(api) {
exclude: ["transform-typeof-symbol"],
};
const envOpts = Object.assign({}, envOptsNoTargets);
let transformRuntimeOpts = null;

let convertESM = true;
let ignoreLib = true;
let includeRuntime = false;
const nodeVersion = "6.9";
// The vast majority of our src files are modules, but we use
// unambiguous to keep things simple until we get around to renaming
// the modules to be more easily distinguished from CommonJS
const unambiguousSources = [
"packages/*/src",
"packages/*/test",
"codemods/*/src",
"codemods/*/test",
"eslint/*/src",
"eslint/*/test",
];

switch (env) {
// Configs used during bundling builds.
case "babel-parser":
case "rollup":
convertESM = false;
ignoreLib = false;
// rollup-commonjs will converts node_modules to ESM
unambiguousSources.push(
"**/node_modules",
// todo: remove this after it is rewritten into ESM
"packages/babel-preset-env/data"
);
envOpts.targets = {
node: nodeVersion,
};
break;
case "standalone":
convertESM = false;
ignoreLib = false;
includeRuntime = true;
unambiguousSources.push(
"**/node_modules",
"packages/babel-preset-env/data"
);
// targets to browserslists: defaults
break;
case "production":
// Config during builds before publish.
Expand All @@ -51,17 +70,6 @@ module.exports = function(api) {
break;
}

if (includeRuntime) {
const babelRuntimePackageJSONPath = require.resolve(
"@babel/runtime/package.json"
);
const path = require("path");
transformRuntimeOpts = {
version: require(babelRuntimePackageJSONPath).version,
absoluteRuntime: path.dirname(babelRuntimePackageJSONPath),
};
}

const config = {
// Our dependencies are all standard CommonJS, along with all sorts of
// other random files in Babel's codebase, so we use script as the default,
Expand Down Expand Up @@ -116,31 +124,9 @@ module.exports = function(api) {
presets: [["@babel/env", envOptsNoTargets]],
},
{
// The vast majority of our src files are modules, but we use
// unambiguous to keep things simple until we get around to renaming
// the modules to be more easily distinguished from CommonJS
test: [
"packages/*/src",
"packages/*/test",
"codemods/*/src",
"codemods/*/test",
"eslint/*/src",
"eslint/*/test",
],
test: unambiguousSources,
sourceType: "unambiguous",
},
{
// The runtime transform shouldn't process its own runtime or core-js.
exclude: [
"packages/babel-runtime",
/[\\/]node_modules[\\/](?:@babel\/runtime|babel-runtime|core-js)[\\/]/,
],
plugins: [
includeRuntime
? ["@babel/transform-runtime", transformRuntimeOpts]
: null,
].filter(Boolean),
},
].filter(Boolean),
};

Expand Down

0 comments on commit a0bed42

Please sign in to comment.