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

Implements relativeRuntime #10378

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

arcanis
Copy link
Contributor

@arcanis arcanis commented Aug 31, 2019

Q                       A
Fixed Issues? Fixes #10355
Minor: New Feature? Yes
Tests Added + Pass? Yes
Documentation PR Link babel/website#2091
Any Dependency Changes? No
License MIT

This PR adds a counterpart to absoluteRuntime named relativeRuntime which, when used, will hardcode the relative path between the transpiled file and the runtime within its import tag. This will help with setups where the runtime comes from a package deep within the dependency tree (think Next.js or CRA) and you want the build artifacts to work the same way across various machines (where absolute paths would break).

@babel-bot
Copy link
Collaborator

babel-bot commented Sep 7, 2019

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/11518/

@arcanis
Copy link
Contributor Author

arcanis commented Sep 7, 2019

🥳 Ready to review, @nicolo-ribaudo!

@nicolo-ribaudo nicolo-ribaudo added the PR: New Feature 🚀 A type of pull request used for our changelog categories label Sep 8, 2019
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

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

Could you create a "fake" node_modules/@babel/runtime in packages/babel-plugin-transform-runtime/test, to avoid having the fixtures depend on how yarn hoists the "real" @babel/runtime?

}
if (absoluteRuntime !== false && relativeRuntime !== false) {
throw new Error(
"The 'absoluteRuntime' and 'relativeRuntime' settings cannot be enabled at the same time",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"The 'absoluteRuntime' and 'relativeRuntime' settings cannot be enabled at the same time",
"The 'absoluteRuntime' and 'relativeRuntime' options cannot be enabled at the same time",

(I think? I'm not a native speaker)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, plus it's more in line with the other messages 👍

Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

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

Could you create a "fake" node_modules/@babel/runtime in packages/babel-plugin-transform-runtime/test, to avoid having the fixtures depend on how yarn hoists the "real" @babel/runtime?

Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

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

I think that this implementation has a bug when the input file is not in the same folder as the config file.

@babel/runtime should be resolved (here the PR is correct) relative to "config file path + relativeRuntime option" (the dirname parameter received by the plugin), so that this has the same meaning for every file:

{
  "plugins": [
    ["@babel/plugin-transform-runtime", {
      "relativeRuntime": "."
    }]
   ]
}

On the other hand, the path put in the import statement should be relative to the input file: you should use this.dirname (which you can get inside the post(...) method using path.dirname(this.filename)).
If this.filename is undefined, it should throw an error because it isn't possible to locate @babel/runtime relative to the input file.

cc @loganfsmyth Are my expectations the same as yours? (#10355 (comment))

@@ -0,0 +1,7 @@
var _classCallCheck = require("../../../../node_modules/@babel/runtime/helpers/classCallCheck");
Copy link
Member

Choose a reason for hiding this comment

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

I think that this is wrong. Even if it is resolved starting from ./subfolder, the location of @babel/runtime relative to this file has only three ../../../.

I would expect a test for the string version of this option to have another node_modules folder inside ./subfolder: then this path should look like

var _classCallCheck = require("./subfolder/node_modules/@babel/runtime/helpers/classCallCheck");

@nicolo-ribaudo nicolo-ribaudo added this to the v7.7.0 milestone Sep 17, 2019
} else if (relativeRuntime !== false) {
modulePath = resolveRelativeRuntime(
moduleName,
path.resolve(dirname, relativeRuntime === true ? "." : relativeRuntime),
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't match my expectations. Wouldn't we need to calculate this path relative to the JS file being compiled, rather than using the directory?

I also wanted this to strictly be a boolean option because I think of the flags this way:

  • absoluteRuntime
    • false to just inject @babel/runtime/<whatever>
    • true to resolve that to a specific path first
  • useRelativeRuntime
    • only allowed when absoluteRuntime is true or a string
    • false - current behavior
    • true - take the resolved path from before and resolve it relative to the JS file it is being inserted into, instead of inserting an absolute path.

If I were doing this from scratch, these might have been nicer as

type Opts = {
  resolveRuntime?: boolean | string,
  resolveRelativePath?: boolean,
};

or

type Opts = {
  resolve?: boolean | string | {
    dirname?: string,
    relative?: boolean,
  },
};

or something

@arcanis
Copy link
Contributor Author

arcanis commented Oct 1, 2019

Yep you're both right - I'll update this PR. Would you know what's the best way to obtain the path of the file being processed during transformation? Local variable set during pre(file), maybe?

@loganfsmyth
Copy link
Member

The same way we assign this.addDefaultImport in pre, we should probably assign this.runtimeModuleName generated from moduleName and this.filename.

Note that this.filename can be undefined, so we should throw a useful error in that case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: New Feature 🚀 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Babel plugin absoluteRuntime should support relative paths
5 participants