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

Specify runtime exports #10853

Merged
merged 9 commits into from Oct 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Expand Up @@ -52,6 +52,7 @@ jobs:
- name: Generate coverage report
run: |
make -j test-ci-coverage
yarn test:esm
- name: Upload coverage report
uses: codecov/codecov-action@v1
with:
Expand Down
7 changes: 2 additions & 5 deletions .gitignore
Expand Up @@ -7,9 +7,8 @@
.pnp.js

.DS_Store
/node_modules
/.github/actions/*/node_modules
/packages/*/node_modules
**/node_modules
!**/test/fixtures/**/node_modules
/packages/*/LICENSE
!/packages/babel-parser/LICENSE
!/packages/babel-plugin-transform-object-assign/LICENSE
Expand Down Expand Up @@ -63,13 +62,11 @@ packages/babel-standalone/babel.js
packages/babel-standalone/babel.js.map
packages/babel-standalone/babel.min.js
/codemods/*/lib
/codemods/*/node_modules
/packages/babel-parser/build
.idea/
/.changelog

/eslint/*/lib
/eslint/*/node_modules
/eslint/*/LICENSE
!/packages/babel-eslint-plugin/LICENSE
/.vscode
6 changes: 4 additions & 2 deletions package.json
Expand Up @@ -9,7 +9,8 @@
"fix": "make fix",
"lint": "make lint",
"test": "make test",
"version": "yarn --immutable-cache && git add yarn.lock"
"version": "yarn --immutable-cache && git add yarn.lock",
"test:esm": "node test/esm/index.mjs"
},
"devDependencies": {
"@babel/cli": "^7.11.6",
Expand Down Expand Up @@ -69,7 +70,8 @@
"workspaces": [
"codemods/*",
"eslint/*",
"packages/*"
"packages/*",
"test/esm"
],
"resolutions": {
"@lerna/version": "patch:@lerna/version@npm:3.20.2#.yarn-patches/@lerna/version.patch",
Expand Down
88 changes: 63 additions & 25 deletions packages/babel-plugin-transform-runtime/scripts/build-dist.js
Expand Up @@ -90,32 +90,68 @@ function writeCoreJS({
`module.exports = require("${corejsRoot}/${corejsPath}");`
);
});

writeCorejsExports(pkgDirname, runtimeRoot, paths);
}

function writeCorejsExports(pkgDirname, runtimeRoot, paths) {
const pkgJsonPath = require.resolve(`${pkgDirname}/package.json`);
const pkgJson = require(pkgJsonPath);
const exports = pkgJson.exports;
// Export `./core-js/` so `import "@babel/runtime-corejs3/core-js/some-feature.js"` works
exports[`./${runtimeRoot}/`] = `./${runtimeRoot}/`;
for (const corejsPath of paths) {
// Export `./core-js/some-feature` so `import "@babel/runtime-corejs3/core-js/some-feature"` also works
const corejsExportPath = `./${runtimeRoot}/${corejsPath}`;
exports[corejsExportPath] = corejsExportPath + ".js";
}
pkgJson.exports = exports;
outputFile(pkgJsonPath, JSON.stringify(pkgJson, undefined, 2) + "\n");
}

function writeHelpers(runtimeName, { corejs } = {}) {
writeHelperFiles(runtimeName, { corejs, esm: false });
writeHelperFiles(runtimeName, { corejs, esm: true });
const helperPaths = writeHelperFiles(runtimeName, { corejs, esm: false });
const helperESMPaths = writeHelperFiles(runtimeName, { corejs, esm: true });
writeHelperExports(runtimeName, helperPaths.concat(helperESMPaths));
}

function writeHelperExports(runtimeName, helperPaths) {
const helperSubExports = {};
for (const helperPath of helperPaths) {
helperSubExports[helperPath.replace(".js", "")] = helperPath;
}
const exports = {
"./helpers/": "./helpers/",
...helperSubExports,
"./package.json": "./package.json",
"./regenerator": "./regenerator/index.js",
"./regenerator/": "./regenerator/",

This comment was marked as outdated.

};
const pkgDirname = getRuntimeRoot(runtimeName);
const pkgJsonPath = require.resolve(`${pkgDirname}/package.json`);
const pkgJson = require(pkgJsonPath);
pkgJson.exports = exports;
outputFile(pkgJsonPath, JSON.stringify(pkgJson, undefined, 2) + "\n");
}
function writeHelperFiles(runtimeName, { esm, corejs }) {
const pkgDirname = getRuntimeRoot(runtimeName);

const helperPaths = [];
for (const helperName of helpers.list) {
const helperFilename = path.join(
pkgDirname,
"helpers",
esm ? "esm" : "",
`${helperName}.js`
);

const helperPath =
"./" + path.join("helpers", esm ? "esm" : "", `${helperName}.js`);
const helperFilename = path.join(pkgDirname, helperPath);
outputFile(
helperFilename,
buildHelper(runtimeName, pkgDirname, helperFilename, helperName, {
esm,
corejs,
})
);

helperPaths.push(helperPath);
}

return helperPaths;
}

function getRuntimeRoot(runtimeName) {
Expand Down Expand Up @@ -171,11 +207,7 @@ function buildHelper(
transformRuntime,
{ corejs, useESModules: esm, version: runtimeVersion },
],
buildRuntimeRewritePlugin(
runtimeName,
path.relative(path.dirname(helperFilename), pkgDirname),
helperName
),
buildRuntimeRewritePlugin(runtimeName, helperName, esm),
],
overrides: [
{
Expand All @@ -186,12 +218,19 @@ function buildHelper(
}).code;
}

function buildRuntimeRewritePlugin(runtimeName, relativePath, helperName) {
function adjustImportPath(node, relativePath) {
node.value =
helpers.list.indexOf(node.value) !== -1
? `./${node.value}`
: node.value.replace(runtimeName + "/", relativePath + "/");
function buildRuntimeRewritePlugin(runtimeName, helperName, esm) {
const helperPath = esm ? "helpers/esm" : "helpers";
/**
* rewrite helpers imports to runtime imports
* @example
* adjustImportPath(ast`"setPrototypeOf"`)
* // returns ast`"@babel/runtime/helpers/esm/setPrototypeOf"`
* @param {*} node The string literal contains import path
*/
function adjustImportPath(node) {
if (helpers.list.includes(node.value)) {
node.value = `${runtimeName}/${helperPath}/${node.value}`;
}
}

return {
Expand All @@ -206,7 +245,7 @@ function buildRuntimeRewritePlugin(runtimeName, relativePath, helperName) {
},
visitor: {
ImportDeclaration(path) {
adjustImportPath(path.get("source").node, relativePath);
adjustImportPath(path.get("source").node);
},
CallExpression(path) {
if (
Expand All @@ -217,9 +256,8 @@ function buildRuntimeRewritePlugin(runtimeName, relativePath, helperName) {
return;
}

// replace any reference to @babel/runtime and other helpers
// with a relative path
adjustImportPath(path.get("arguments")[0].node, relativePath);
// replace reference to internal helpers with @babel/runtime import path
adjustImportPath(path.get("arguments")[0].node);
},
},
};
Expand Down
6 changes: 3 additions & 3 deletions packages/babel-runtime-corejs2/helpers/esm/iterableToArray.js
@@ -1,6 +1,6 @@
import _Array$from from "../../core-js/array/from";
import _isIterable from "../../core-js/is-iterable";
import _Symbol from "../../core-js/symbol";
import _Array$from from "@babel/runtime-corejs2/core-js/array/from";
import _isIterable from "@babel/runtime-corejs2/core-js/is-iterable";
import _Symbol from "@babel/runtime-corejs2/core-js/symbol";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For users using PnP, is it allowed for a package to import itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yarn PnP does not support esm yet: yarnpkg/berry#638

@merceyz Does PnP support require("package/itself")?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's totally fine

export default function _iterableToArray(iter) {
if (typeof _Symbol !== "undefined" && _isIterable(Object(iter))) return _Array$from(iter);
}
4 changes: 2 additions & 2 deletions packages/babel-runtime-corejs2/helpers/esm/temporalRef.js
@@ -1,5 +1,5 @@
import undef from "./temporalUndefined";
import err from "./tdz";
import undef from "@babel/runtime-corejs2/helpers/esm/temporalUndefined";
import err from "@babel/runtime-corejs2/helpers/esm/tdz";
export default function _temporalRef(val, name) {
return val === undef ? err(name) : val;
}
8 changes: 4 additions & 4 deletions packages/babel-runtime-corejs2/helpers/esm/toArray.js
@@ -1,7 +1,7 @@
import arrayWithHoles from "./arrayWithHoles";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, some corejs 2 helper files are tracked in git repository. Yet it is convenient so you can review the actual change of helper imports.

/cc @rwjblue Will ember support self referencing package? In this case @babel/runtime-corejs2 is referencing itself. The import path extension .js is not added so this part should work with amd.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yet it is convenient so you can review the actual change of helper imports.

That's exactly why we don't ignore some of these files 😛

import iterableToArray from "./iterableToArray";
import unsupportedIterableToArray from "./unsupportedIterableToArray";
import nonIterableRest from "./nonIterableRest";
import arrayWithHoles from "@babel/runtime-corejs2/helpers/esm/arrayWithHoles";
import iterableToArray from "@babel/runtime-corejs2/helpers/esm/iterableToArray";
import unsupportedIterableToArray from "@babel/runtime-corejs2/helpers/esm/unsupportedIterableToArray";
import nonIterableRest from "@babel/runtime-corejs2/helpers/esm/nonIterableRest";
export default function _toArray(arr) {
return arrayWithHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableRest();
}
6 changes: 3 additions & 3 deletions packages/babel-runtime-corejs2/helpers/iterableToArray.js
@@ -1,8 +1,8 @@
var _Array$from = require("../core-js/array/from");
var _Array$from = require("@babel/runtime-corejs2/core-js/array/from");

var _isIterable = require("../core-js/is-iterable");
var _isIterable = require("@babel/runtime-corejs2/core-js/is-iterable");

var _Symbol = require("../core-js/symbol");
var _Symbol = require("@babel/runtime-corejs2/core-js/symbol");

function _iterableToArray(iter) {
if (typeof _Symbol !== "undefined" && _isIterable(Object(iter))) return _Array$from(iter);
Expand Down