Compare commits
222 Commits
v7.0.0-bet
...
v7.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3af623678f | ||
|
|
96528d36df | ||
|
|
5de12c26f6 | ||
|
|
4b5a55d937 | ||
|
|
036c429ce1 | ||
|
|
3c46e75b8f | ||
|
|
106907e605 | ||
|
|
387cda8fbb | ||
|
|
86c10ff4f3 | ||
|
|
6d5392554f | ||
|
|
0b25e3327c | ||
|
|
b6455c611b | ||
|
|
313960e601 | ||
|
|
9e4c56f990 | ||
|
|
119db23ee3 | ||
|
|
3432792568 | ||
|
|
cc4ee350e4 | ||
|
|
5bd79c70a5 | ||
|
|
01f6f4c66d | ||
|
|
000fa83b9e | ||
|
|
efb34aa7dc | ||
|
|
ab928713af | ||
|
|
3de053cc6c | ||
|
|
110779e9f3 | ||
|
|
8070a2204d | ||
|
|
9f4e2f81d8 | ||
|
|
415d79bdfe | ||
|
|
62eb32677c | ||
|
|
7da7e760a6 | ||
|
|
bd44902024 | ||
|
|
6480ae4a9f | ||
|
|
80b3362fcc | ||
|
|
8bc0182489 | ||
|
|
e9d861537f | ||
|
|
153ad4c6f3 | ||
|
|
218d69007e | ||
|
|
f838a7e9f1 | ||
|
|
6349118bed | ||
|
|
8bbb10c021 | ||
|
|
f614809002 | ||
|
|
b445b79734 | ||
|
|
b6eaaa2496 | ||
|
|
e2471337f4 | ||
|
|
826edd0bd5 | ||
|
|
f434a50829 | ||
|
|
5895277b32 | ||
|
|
62114b807b | ||
|
|
2abd7839e1 | ||
|
|
b8dcd6f593 | ||
|
|
fe556c502d | ||
|
|
ab62a94399 | ||
|
|
d83d141e00 | ||
|
|
cb17f07ac9 | ||
|
|
21b9b2e42d | ||
|
|
2a8ebbe7ae | ||
|
|
9add6d88f5 | ||
|
|
2d2f37fa6c | ||
|
|
7846eaebaa | ||
|
|
d45ee5e025 | ||
|
|
f699f1bbbf | ||
|
|
f0283572a5 | ||
|
|
90566103a6 | ||
|
|
cf8058e5b6 | ||
|
|
90a174e7c4 | ||
|
|
9c707f9670 | ||
|
|
53e4d74ebe | ||
|
|
98ff2ce877 | ||
|
|
0ffc8ed209 | ||
|
|
e6d198eef5 | ||
|
|
86aacad2bc | ||
|
|
6eab6f5863 | ||
|
|
555ee80f43 | ||
|
|
a94cbf760a | ||
|
|
0bc3027554 | ||
|
|
6f3093b557 | ||
|
|
7489f8da7b | ||
|
|
dccaec7691 | ||
|
|
c992f5b61e | ||
|
|
5cd1276a27 | ||
|
|
2af7a33c4e | ||
|
|
ffe04d9195 | ||
|
|
b33823e7f8 | ||
|
|
007bfb6565 | ||
|
|
c8faa34848 | ||
|
|
5bcca0123a | ||
|
|
1d987fb655 | ||
|
|
06e5c46c8d | ||
|
|
52b800decb | ||
|
|
01d969a182 | ||
|
|
7d99a96f9f | ||
|
|
ad1de09b5f | ||
|
|
6b91d6434d | ||
|
|
18796173ab | ||
|
|
eb3334a14e | ||
|
|
5e00c96368 | ||
|
|
b4d18f4764 | ||
|
|
981bff08e4 | ||
|
|
7d641d2e74 | ||
|
|
f2882d570a | ||
|
|
cc5aeb3b50 | ||
|
|
d164f820e6 | ||
|
|
43aa61d6be | ||
|
|
ca1c98b255 | ||
|
|
0963dbddea | ||
|
|
2058e0686e | ||
|
|
c0013264b7 | ||
|
|
442ead701c | ||
|
|
5fb3696955 | ||
|
|
69cca412eb | ||
|
|
3bee37b14d | ||
|
|
bc757c8b75 | ||
|
|
c558dedd7b | ||
|
|
0879a6d608 | ||
|
|
51eef099b3 | ||
|
|
daf0ca8680 | ||
|
|
0200a3e510 | ||
|
|
27c39c512d | ||
|
|
70eb206c03 | ||
|
|
229179b8aa | ||
|
|
6baa36cdc5 | ||
|
|
a40f54f847 | ||
|
|
6226c52f43 | ||
|
|
25153359f7 | ||
|
|
2351a638b5 | ||
|
|
bc6f0f989d | ||
|
|
af7ab71486 | ||
|
|
ac13c302f7 | ||
|
|
b396cdcbe5 | ||
|
|
8dcfabd0d7 | ||
|
|
e45d5c3b65 | ||
|
|
8ff675ad69 | ||
|
|
a955efa3e3 | ||
|
|
51db3e9a5d | ||
|
|
41ca312545 | ||
|
|
a192f8beb4 | ||
|
|
f03adbadf4 | ||
|
|
97145ad01e | ||
|
|
25810d2609 | ||
|
|
5f58117790 | ||
|
|
dca2631ef0 | ||
|
|
ba11d9fa7c | ||
|
|
e06cf20d2e | ||
|
|
df1afa3160 | ||
|
|
cec93c01ce | ||
|
|
0a8367c979 | ||
|
|
ac5d2ba984 | ||
|
|
040ba2bf53 | ||
|
|
98f0808a22 | ||
|
|
bdcfb697a6 | ||
|
|
0341d299c8 | ||
|
|
1a7765712e | ||
|
|
b87c43d894 | ||
|
|
02c4a28608 | ||
|
|
4260ffd7ec | ||
|
|
25c3f0d689 | ||
|
|
21b03c35d3 | ||
|
|
ee1ee0e7ae | ||
|
|
73f8059ea0 | ||
|
|
70e3454d7a | ||
|
|
9dab691302 | ||
|
|
95fc38cecf | ||
|
|
84e76e2d49 | ||
|
|
0d9eef4750 | ||
|
|
d2ed7bbc8d | ||
|
|
5b5ac1f366 | ||
|
|
fa1547d8f8 | ||
|
|
b42b21f25c | ||
|
|
6dca0ff9bf | ||
|
|
3e9b59c0f1 | ||
|
|
3f6c475aae | ||
|
|
5c31e501d7 | ||
|
|
ed6b4e0e40 | ||
|
|
8615b6fe57 | ||
|
|
95fa5a66b1 | ||
|
|
c94355c1c9 | ||
|
|
839bf68d1f | ||
|
|
8198b1b334 | ||
|
|
d608535719 | ||
|
|
0353ce9ed5 | ||
|
|
65ca968f8b | ||
|
|
77445cb044 | ||
|
|
7c4509e280 | ||
|
|
87ae286bc3 | ||
|
|
9c1b3e8dc1 | ||
|
|
39d07638cf | ||
|
|
e887eecda4 | ||
|
|
a3e622ad15 | ||
|
|
494a56df5f | ||
|
|
8060ae5dae | ||
|
|
bd4ebc11c1 | ||
|
|
80cefaff2f | ||
|
|
e9d5073af1 | ||
|
|
c8fb48ffd6 | ||
|
|
55ef39eb87 | ||
|
|
91e1e1728c | ||
|
|
acf509bab5 | ||
|
|
4f312f5739 | ||
|
|
696f84468e | ||
|
|
71fd37067e | ||
|
|
7142a79eb9 | ||
|
|
1a6855eff2 | ||
|
|
1de36948ac | ||
|
|
b28ffedead | ||
|
|
a5edab7393 | ||
|
|
725e6a01c0 | ||
|
|
224ce38882 | ||
|
|
8c46fd159f | ||
|
|
47201db61e | ||
|
|
138d60922c | ||
|
|
cfb386ff03 | ||
|
|
9e7fe0ab49 | ||
|
|
e31e907d5f | ||
|
|
4da4728bf5 | ||
|
|
0112479ba9 | ||
|
|
408124438a | ||
|
|
eab4c0e93e | ||
|
|
d06bf993db | ||
|
|
1076018c4c | ||
|
|
07ff8f30f5 | ||
|
|
e6ba0ab82c | ||
|
|
2afe9404fe | ||
|
|
037fee8ffb |
@@ -1,5 +0,0 @@
|
||||
# Ensure babel-register won't compile fixtures, or try to recompile compiled code.
|
||||
packages/*/test/fixtures
|
||||
packages/*/lib
|
||||
packages/babel-standalone/babel.js
|
||||
packages/babel-preset-env-standalone/babel-preset-env.js
|
||||
80
.babelrc.js
80
.babelrc.js
@@ -1,80 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function(api) {
|
||||
const env = api.env();
|
||||
|
||||
const includeCoverage = process.env.BABEL_COVERAGE === "true";
|
||||
|
||||
const envOpts = {
|
||||
loose: true,
|
||||
modules: false,
|
||||
exclude: ["transform-typeof-symbol"],
|
||||
};
|
||||
|
||||
let convertESM = true;
|
||||
|
||||
switch (env) {
|
||||
// Configs used during bundling builds.
|
||||
case "babylon":
|
||||
case "standalone":
|
||||
convertESM = false;
|
||||
break;
|
||||
case "production":
|
||||
// Config during builds before publish.
|
||||
break;
|
||||
case "development":
|
||||
envOpts.debug = true;
|
||||
envOpts.targets = {
|
||||
node: "current",
|
||||
};
|
||||
break;
|
||||
case "test":
|
||||
envOpts.targets = {
|
||||
node: "current",
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
const config = {
|
||||
comments: false,
|
||||
presets: [["@babel/env", envOpts]],
|
||||
plugins: [
|
||||
// TODO: Use @babel/preset-flow when
|
||||
// https://github.com/babel/babel/issues/7233 is fixed
|
||||
"@babel/plugin-transform-flow-strip-types",
|
||||
["@babel/proposal-class-properties", { loose: true }],
|
||||
"@babel/proposal-export-namespace-from",
|
||||
"@babel/proposal-numeric-separator",
|
||||
["@babel/proposal-object-rest-spread", { useBuiltIns: true }],
|
||||
|
||||
// Explicitly use the lazy version of CommonJS modules.
|
||||
convertESM ? ["@babel/transform-modules-commonjs", { lazy: true }] : null,
|
||||
].filter(Boolean),
|
||||
overrides: [
|
||||
{
|
||||
test: "packages/babylon",
|
||||
plugins: [
|
||||
"babel-plugin-transform-charcodes",
|
||||
["@babel/transform-for-of", { assumeArray: true }],
|
||||
],
|
||||
},
|
||||
{
|
||||
test: "./packages/babel-register",
|
||||
plugins: [
|
||||
// Override the root options to disable lazy imports for babel-register
|
||||
// because otherwise the require hook will try to lazy-import things
|
||||
// leading to dependency cycles.
|
||||
convertESM ? "@babel/transform-modules-commonjs" : null,
|
||||
].filter(Boolean),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// we need to do this as long as we do not test everything from source
|
||||
if (includeCoverage) {
|
||||
config.auxiliaryCommentBefore = "istanbul ignore next";
|
||||
config.plugins.push("babel-plugin-istanbul");
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
build:
|
||||
working_directory: ~/babel
|
||||
docker:
|
||||
- image: circleci/node:9
|
||||
- image: circleci/node:10
|
||||
steps:
|
||||
- checkout
|
||||
- restore-cache: *restore-yarn-cache
|
||||
|
||||
@@ -22,4 +22,4 @@ packages/babel-preset-env-standalone/babel-preset-env.js
|
||||
packages/babel-preset-env-standalone/babel-preset-env.min.js
|
||||
packages/babel-standalone/babel.js
|
||||
packages/babel-standalone/babel.min.js
|
||||
packages/babylon/test/expressions
|
||||
packages/babel-parser/test/expressions
|
||||
|
||||
59
.github/ISSUE_TEMPLATE.md
vendored
59
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,63 +1,6 @@
|
||||
<!---
|
||||
Thanks for filing an issue 😄 ! Before you submit, please read the following:
|
||||
|
||||
Check the other issue templates if you are trying to submit a bug report, feature request, or question
|
||||
Search open/closed issues before submitting since someone might have asked the same thing before!
|
||||
|
||||
If you have a support request or question please submit them to one of this resources:
|
||||
|
||||
* Slack Community: https://babeljs.slack.com (you can sign-up at https://slack.babeljs.io/ for an invite)
|
||||
* StackOverflow: http://stackoverflow.com/questions/tagged/babeljs using the tag `babeljs`
|
||||
* Also have a look at the readme for more information on how to get support:
|
||||
https://github.com/babel/babel/blob/master/README.md
|
||||
|
||||
Issues on GitHub are only related to problems of Babel itself and we cannot answer
|
||||
support questions here.
|
||||
-->
|
||||
|
||||
Choose one: is this a bug report or feature request?
|
||||
|
||||
<!--- Provide a general summary of the issue in the title above -->
|
||||
|
||||
### Input Code
|
||||
<!--- If you're describing a bug, please let us know which sample code reproduces your problem -->
|
||||
<!--- If you have link to our REPL or a standalone repo please link that! -->
|
||||
|
||||
```js
|
||||
var your => (code) => here;
|
||||
```
|
||||
|
||||
### Babel/Babylon Configuration (.babelrc, package.json, cli command)
|
||||
<!--- If describing a bug, tell us what your babel configuration looks like -->
|
||||
|
||||
```js
|
||||
{
|
||||
"your": { "config": "here" }
|
||||
}
|
||||
```
|
||||
|
||||
### Expected Behavior
|
||||
<!--- If you're describing a bug, tell us what should happen -->
|
||||
<!--- If you're suggesting a change/improvement, tell us how it should work -->
|
||||
|
||||
### Current Behavior
|
||||
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
|
||||
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
|
||||
|
||||
### Possible Solution
|
||||
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
|
||||
<!--- or ideas how to implement the addition or change -->
|
||||
|
||||
### Context
|
||||
<!--- How has this issue affected you? What are you trying to accomplish? -->
|
||||
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
|
||||
|
||||
### Your Environment
|
||||
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
||||
|
||||
| software | version(s)
|
||||
| ---------------- | -------
|
||||
| Babel |
|
||||
| Babylon | <!-- This is only needed if you are using Babylon directly -->
|
||||
| node |
|
||||
| npm |
|
||||
| Operating System |
|
||||
|
||||
41
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
Normal file
41
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: 🐛 Bug Report
|
||||
about: If something isn't working as expected 🤔.
|
||||
|
||||
---
|
||||
|
||||
## Bug Report
|
||||
|
||||
**Current Behavior**
|
||||
A clear and concise description of the behavior.
|
||||
|
||||
**Input Code**
|
||||
- REPL or Repo link if applicable:
|
||||
|
||||
```js
|
||||
var your => (code) => here;
|
||||
```
|
||||
|
||||
**Expected behavior/code**
|
||||
A clear and concise description of what you expected to happen (or code).
|
||||
|
||||
**Babel Configuration (.babelrc, package.json, cli command)**
|
||||
|
||||
```js
|
||||
{
|
||||
"your": { "config": "here" }
|
||||
}
|
||||
```
|
||||
|
||||
**Environment**
|
||||
- Babel version(s): [e.g. v6.0.0, v7.0.0-beta.34]
|
||||
- Node/npm version: [e.g. Node 8/npm 5]
|
||||
- OS: [e.g. OSX 10.13.4, Windows 10]
|
||||
- Monorepo [e.g. yes/no/Lerna]
|
||||
- How you are using Babel: [e.g. `cli`, `register`, `loader`]
|
||||
|
||||
**Possible Solution**
|
||||
<!--- Only if you have suggestions on a fix for the bug -->
|
||||
|
||||
**Additional context/Screenshots**
|
||||
Add any other context about the problem here. If applicable, add screenshots to help explain.
|
||||
20
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: 🚀 Feature Request
|
||||
about: I have a suggestion (and may want to implement it 🙂)!
|
||||
|
||||
---
|
||||
|
||||
## Feature Request
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I have an issue when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen. Add any considered drawbacks.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Teachability, Documentation, Adoption, Migration Strategy**
|
||||
If you can, explain how users will be able to use this and possibly write out a version the docs.
|
||||
Maybe a screenshot or design?
|
||||
41
.github/ISSUE_TEMPLATE/Regression-v7.md
vendored
Normal file
41
.github/ISSUE_TEMPLATE/Regression-v7.md
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: 💥 v7 Regression
|
||||
about: Report an unexpected behavior in v7 from v6 (Check the upgrade guide first ✌️)
|
||||
|
||||
---
|
||||
|
||||
# v7 Regression
|
||||
|
||||
> First check out: https://new.babeljs.io/docs/en/next/v7-migration.html
|
||||
> Also a partial upgrade tool: https://github.com/babel/babel-upgrade
|
||||
|
||||
**Potential Commit/PR that introduced the regression**
|
||||
If you have time to investigate, what PR/date introduced this issue.
|
||||
|
||||
**Describe the regression**
|
||||
A clear and concise description of what the regression is.
|
||||
|
||||
**Input Code**
|
||||
<!--- If you have link to our REPL or a standalone repo please link that! -->
|
||||
|
||||
```js
|
||||
var your => (code) => here;
|
||||
```
|
||||
|
||||
**Babel Configuration (.babelrc, package.json, cli command)**
|
||||
|
||||
```js
|
||||
{
|
||||
"your": { "config": "here" }
|
||||
}
|
||||
```
|
||||
|
||||
**Expected behavior/code**
|
||||
A clear and concise description of what you expected to happen (or code).
|
||||
|
||||
**Environment**
|
||||
- Babel version(s): [e.g. v6.0.0, v7.0.0-beta.34]
|
||||
- Node/npm version: [e.g. Node 8/npm 5]
|
||||
- OS: [e.g. OSX 10.13.4, Windows 10]
|
||||
- Monorepo [e.g. yes/no/Lerna]
|
||||
- How you are using Babel: [e.g. `cli`, `register`, `loader`]
|
||||
16
.github/ISSUE_TEMPLATE/Support_question.md
vendored
Normal file
16
.github/ISSUE_TEMPLATE/Support_question.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: 🤗 Support Question
|
||||
about: If you have a question 💬, please check out our Slack or StackOverflow!
|
||||
|
||||
---
|
||||
|
||||
--------------^ Click "Preview" for a nicer view!
|
||||
We primarily use GitHub as an issue tracker; for usage and support questions, please check out these resources below. Thanks! 😁.
|
||||
|
||||
---
|
||||
|
||||
* Slack Community Chat: https://babeljs.slack.com (you can sign-up at https://slack.babeljs.io/ for an invite)
|
||||
* StackOverflow: https://stackoverflow.com/questions/tagged/babeljs using the tag `babeljs`
|
||||
* Twitter: If it's just a quick question you can ping our Twitter: https://twitter.com/babeljs
|
||||
* Also have a look at the readme for more information on how to get support:
|
||||
https://github.com/babel/babel/blob/master/README.md
|
||||
24
.github/ISSUE_TEMPLATE/Support_us.md
vendored
Normal file
24
.github/ISSUE_TEMPLATE/Support_us.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
name: 🤝 Support us on Babel
|
||||
about: If you would like to support our efforts in maintaining this community-driven project 🙌!
|
||||
|
||||
---
|
||||
|
||||
--------------^ Click "Preview" for a nicer view!
|
||||
> Open Collective: https://opencollective.com/babel
|
||||
> Henry's Patreon: https://www.patreon.com/henryzhu
|
||||
|
||||
Help support Babel!
|
||||
|
||||
Babel has always been a community project, not really backed or owned by any single (or group) of companies. While some maintainers used to work at Facebook (and Henry at Adobe) no one was working on it full time and there certainly isn't a huge company or team anywhere doing all this work.
|
||||
|
||||
---
|
||||
|
||||
As a group of volunteers you can help us in a few ways
|
||||
|
||||
- Giving developer time on the project. (Message us on [Twitter](https://twitter.com/babeljs) or [Slack](https://slack.babeljs.io/) for guidance). Companies should be paying their employees to contribute back to the open source projects they use everyday.
|
||||
- Giving funds by becoming one of our sponsors/donators!
|
||||
|
||||
If you'd like to sustain the future of the project as a whole, we have an [Open Collective](https://opencollective.com/babel) that you can donate to. This is a way for funds to be allocated to the core team.
|
||||
|
||||
You can also support [Henry](https://github.com/hzoo) directly since I [left my job to work on Babel and Open Source full time](https://twitter.com/left_pad/status/969793227862790144) at my [Patreon](https://www.patreon.com/henryzhu).
|
||||
12
.github/lock.yml
vendored
Normal file
12
.github/lock.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# Configuration for lock-threads - https://github.com/dessant/lock-threads
|
||||
|
||||
# Number of days of inactivity before a closed issue or pull request is locked
|
||||
daysUntilLock: 91
|
||||
# Comment to post before locking. Set to `false` to disable
|
||||
lockComment: false
|
||||
only: issues
|
||||
lockLabel: 'outdated'
|
||||
|
||||
# Issues or pull requests with these labels will not be locked
|
||||
# exemptLabels:
|
||||
# - no-locking
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -42,5 +42,6 @@ packages/babel-preset-env-standalone/babel-preset-env.js
|
||||
packages/babel-preset-env-standalone/babel-preset-env.min.js
|
||||
/codemods/*/lib
|
||||
/codemods/*/node_modules
|
||||
/packages/babylon/build
|
||||
/packages/babel-parser/build
|
||||
.idea/
|
||||
/.changelog
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
package.json
|
||||
packages/babel-preset-env/data
|
||||
|
||||
15
.travis.yml
15
.travis.yml
@@ -5,9 +5,10 @@ language: node_js
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- node_modules
|
||||
- node_modules
|
||||
node_js:
|
||||
# We test the latest version on circleci
|
||||
- '9'
|
||||
- '8'
|
||||
- '6'
|
||||
|
||||
@@ -22,14 +23,14 @@ before_install:
|
||||
install: yarn --ignore-engines
|
||||
|
||||
before_script:
|
||||
- 'if [ "$JOB" = "babylon-flow-tests" ]; then make bootstrap-flow; fi'
|
||||
- 'if [ "$JOB" = "babylon-test262-tests" ]; then make bootstrap-test262; fi'
|
||||
- 'if [ "$JOB" = "babel-parser-flow-tests" ]; then make bootstrap-flow; fi'
|
||||
- 'if [ "$JOB" = "babel-parser-test262-tests" ]; then make bootstrap-test262; fi'
|
||||
|
||||
script:
|
||||
- 'if [ "$JOB" = "test" ]; then make test-ci; fi'
|
||||
- 'if [ "$JOB" = "lint" ]; then make lint && make flow; fi'
|
||||
- 'if [ "$JOB" = "babylon-flow-tests" ]; then make test-flow-ci; fi'
|
||||
- 'if [ "$JOB" = "babylon-test262-tests" ]; then make test-test262-ci; fi'
|
||||
- 'if [ "$JOB" = "babel-parser-flow-tests" ]; then make test-flow-ci; fi'
|
||||
- 'if [ "$JOB" = "babel-parser-test262-tests" ]; then make test-test262-ci; fi'
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
@@ -37,9 +38,9 @@ matrix:
|
||||
- node_js: "node"
|
||||
env: JOB=lint
|
||||
- node_js: "node"
|
||||
env: JOB=babylon-flow-tests
|
||||
env: JOB=babel-parser-flow-tests
|
||||
- node_js: "node"
|
||||
env: JOB=babylon-test262-tests
|
||||
env: JOB=babel-parser-test262-tests
|
||||
|
||||
notifications:
|
||||
slack:
|
||||
|
||||
@@ -24,7 +24,7 @@ contributing, please read the
|
||||
## Not sure where to start?
|
||||
|
||||
- If you aren't just making a documentation change, you'll probably want to learn a bit about a few topics.
|
||||
- [ASTs](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (Abstract Syntax Tree): The Babel AST [spec](https://github.com/babel/babel/blob/master/packages/babylon/ast/spec.md) is a bit different from [ESTree](https://github.com/estree/estree). The differences are listed [here](https://github.com/babel/babel/tree/master/packages/babylon#output).
|
||||
- [ASTs](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (Abstract Syntax Tree): The Babel AST [spec](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md) is a bit different from [ESTree](https://github.com/estree/estree). The differences are listed [here](https://github.com/babel/babel/tree/master/packages/babel-parser#output).
|
||||
- Check out [`/doc`](https://github.com/babel/babel/tree/master/doc) for information about Babel's internals
|
||||
- Check out [the Babel Plugin Handbook](https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md#babel-plugin-handbook) - core plugins are written the same way as any other plugin!
|
||||
- Check out [AST Explorer](http://astexplorer.net/#/scUfOmVOG5) to learn more about ASTs or make your own plugin in the browser
|
||||
@@ -226,19 +226,19 @@ If the test requires a minimum Node version, you can add `minNodeVersion` (must
|
||||
}
|
||||
```
|
||||
|
||||
#### `babylon`
|
||||
#### `@babel/parser` (babylon)
|
||||
|
||||
Writing tests for Babylon is very
|
||||
Writing tests for the babel parser is very
|
||||
similar to the other packages.
|
||||
Inside the `packages/babylon/tests/fixtures` folder are categories/groupings of test fixtures (es2015, flow,
|
||||
Inside the `packages/babel-parser/tests/fixtures` folder are categories/groupings of test fixtures (es2015, flow,
|
||||
etc.). To add a test, create a folder under one of these groupings (or create a new one) with a
|
||||
descriptive name, and add the following:
|
||||
|
||||
* Create an `input.js` file that contains the code you want Babylon to parse.
|
||||
* Create an `input.js` file that contains the code you want the babel parser to parse.
|
||||
|
||||
* Add an `output.json` file with the expected parser output. For added convenience, if there is no `output.json` present, the test runner will generate one for you.
|
||||
|
||||
After writing tests for babylon, just build it by running:
|
||||
After writing tests for @babel/parser, just build it by running:
|
||||
|
||||
```sh
|
||||
$ make build
|
||||
@@ -247,17 +247,17 @@ $ make build
|
||||
Then, to run the tests, use:
|
||||
|
||||
```sh
|
||||
$ TEST_ONLY=babylon make test-only
|
||||
$ TEST_ONLY=babel-parser make test-only
|
||||
```
|
||||
|
||||
#### Bootstrapping expected output
|
||||
|
||||
For both `@babel/plugin-x` and `babylon`, you can easily generate an `output.js`/`output.json` automatically by just providing `input.js` and running the tests as you usually would.
|
||||
For both `@babel/plugin-x` and `@babel/parser`, you can easily generate an `output.js`/`output.json` automatically by just providing `input.js` and running the tests as you usually would.
|
||||
|
||||
```
|
||||
// Example
|
||||
- packages
|
||||
- babylon
|
||||
- babel-parser
|
||||
- test
|
||||
- fixtures
|
||||
- comments
|
||||
@@ -309,14 +309,14 @@ Note that the code shown in Chrome DevTools is compiled code and therefore diffe
|
||||
|
||||
- Create a new issue that describes the proposal (ex: [#538](https://github.com/babel/babylon/issues/538)). Include any relevant information like proposal repo/author, examples, parsing approaches, meeting notes, presentation slides, and more.
|
||||
- The pull request should include:
|
||||
- [ ] An update to the [plugins](https://github.com/babel/babel/tree/master/packages/babylon#plugins) part of the readme. Add a new entry to that list for the new plugin flag (and link to the proposal)
|
||||
- [ ] If any new nodes or modifications need to be added to the AST, update [ast/spec.md](https://github.com/babel/babel/bloc/master/packages/babylon/ast/spec.md)
|
||||
- [ ] Make sure you use the `this.hasPlugin("plugin-name-here")` check in Babylon so that your new plugin code only runs when that flag is turned on (not default behavior)
|
||||
- [ ] An update to the [plugins](https://github.com/babel/babel/tree/master/packages/babel-parser#plugins) part of the readme. Add a new entry to that list for the new plugin flag (and link to the proposal)
|
||||
- [ ] If any new nodes or modifications need to be added to the AST, update [ast/spec.md](https://github.com/babel/babel/bloc/master/packages/babel-parser/ast/spec.md)
|
||||
- [ ] Make sure you use the `this.hasPlugin("plugin-name-here")` check in the babel parser so that your new plugin code only runs when that flag is turned on (not default behavior)
|
||||
- [ ] Add failing/passing tests according to spec behavior
|
||||
- Start working about the Babel transform itself!
|
||||
|
||||
## Internals
|
||||
- AST spec ([babylon/ast/spec.md](https://github.com/babel/babel/blob/master/packages/babylon/ast/spec.md))
|
||||
- AST spec ([babel-parser/ast/spec.md](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md))
|
||||
- Versioning ([doc/design/versioning.md](https://github.com/babel/babel/blob/master/doc/design/versioning.md))
|
||||
- Monorepo ([doc/design/monorepo.md](https://github.com/babel/babel/blob/master/doc/design/monorepo.md))
|
||||
- Compiler environment support ([doc/design/compiler-environment-support.md](https://github.com/babel/babel/blob/master/doc/design/compiler-environment-support.md))
|
||||
|
||||
27
Gulpfile.js
27
Gulpfile.js
@@ -5,7 +5,7 @@ const through = require("through2");
|
||||
const chalk = require("chalk");
|
||||
const newer = require("gulp-newer");
|
||||
const babel = require("gulp-babel");
|
||||
const watch = require("gulp-watch");
|
||||
const gulpWatch = require("gulp-watch");
|
||||
const gutil = require("gulp-util");
|
||||
const filter = require("gulp-filter");
|
||||
const gulp = require("gulp");
|
||||
@@ -98,9 +98,7 @@ function buildRollup(packages) {
|
||||
format: "cjs",
|
||||
plugins: [
|
||||
rollupBabel({
|
||||
envName: "babylon",
|
||||
babelrc: false,
|
||||
extends: "./.babelrc.js",
|
||||
envName: "babel-parser",
|
||||
}),
|
||||
rollupNodeResolve(),
|
||||
],
|
||||
@@ -114,21 +112,26 @@ function buildRollup(packages) {
|
||||
);
|
||||
}
|
||||
|
||||
gulp.task("default", ["build"]);
|
||||
|
||||
gulp.task("build", function() {
|
||||
const bundles = ["packages/babylon"];
|
||||
const bundles = ["packages/babel-parser"];
|
||||
|
||||
return merge([buildBabel(/* exclude */ bundles), buildRollup(bundles)]);
|
||||
});
|
||||
|
||||
gulp.task("default", gulp.series("build"));
|
||||
|
||||
gulp.task("build-no-bundle", () => buildBabel());
|
||||
|
||||
gulp.task("watch", ["build-no-bundle"], function() {
|
||||
watch(sources.map(getGlobFromSource), { debounceDelay: 200 }, function() {
|
||||
gulp.start("build-no-bundle");
|
||||
});
|
||||
});
|
||||
gulp.task(
|
||||
"watch",
|
||||
gulp.series("build-no-bundle", function watch() {
|
||||
gulpWatch(
|
||||
sources.map(getGlobFromSource),
|
||||
{ debounceDelay: 200 },
|
||||
gulp.task("build-no-bundle")
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
registerStandalonePackageTask(
|
||||
gulp,
|
||||
|
||||
17
Makefile
17
Makefile
@@ -1,6 +1,6 @@
|
||||
MAKEFLAGS = -j1
|
||||
FLOW_COMMIT = f193e19cf2185006ea9139bb0e71f31ea93e7b72
|
||||
TEST262_COMMIT = 52f70e2f637731aae92a9c9a2d831310c3ab2e1e
|
||||
FLOW_COMMIT = 395e045c18d537fcbbc552a96ef2cdcd70b4ab52
|
||||
TEST262_COMMIT = f90a52b39609a620c0854e0bd0b3a906c930fd17
|
||||
|
||||
# Fix color output until TravisCI fixes https://github.com/travis-ci/travis-ci/issues/7967
|
||||
export FORCE_COLOR = true
|
||||
@@ -17,8 +17,6 @@ build: clean clean-lib
|
||||
# generate flow and typescript typings
|
||||
node scripts/generators/flow.js > ./packages/babel-types/lib/index.js.flow
|
||||
node scripts/generators/typescript.js > ./packages/babel-types/lib/index.d.ts
|
||||
# generate docs
|
||||
node scripts/generators/docs.js > ./packages/babel-types/README.md
|
||||
ifneq ("$(BABEL_COVERAGE)", "true")
|
||||
make build-standalone
|
||||
make build-preset-env-standalone
|
||||
@@ -52,8 +50,6 @@ lint:
|
||||
./node_modules/.bin/eslint scripts $(SOURCES) '*.js' '**/.*.js' --format=codeframe --rulesdir="./scripts/eslint_rules"
|
||||
|
||||
fix:
|
||||
# The config is hardcoded because otherwise prettier searches for it and also picks up some broken package.json files from tests
|
||||
./node_modules/.bin/prettier --config .prettierrc --write --ignore-path .eslintignore '**/*.json'
|
||||
./node_modules/.bin/eslint scripts $(SOURCES) '*.js' '**/.*.js' --format=codeframe --fix --rulesdir="./scripts/eslint_rules"
|
||||
|
||||
clean: test-clean
|
||||
@@ -87,12 +83,12 @@ bootstrap-flow:
|
||||
cd build/flow && git checkout $(FLOW_COMMIT)
|
||||
|
||||
test-flow:
|
||||
node scripts/tests/flow/run_babylon_flow_tests.js
|
||||
node scripts/tests/flow/run_babel_parser_flow_tests.js
|
||||
|
||||
test-flow-ci: bootstrap test-flow
|
||||
|
||||
test-flow-update-whitelist:
|
||||
node scripts/tests/flow/run_babylon_flow_tests.js --update-whitelist
|
||||
node scripts/tests/flow/run_babel_parser_flow_tests.js --update-whitelist
|
||||
|
||||
bootstrap-test262:
|
||||
rm -rf ./build/test262
|
||||
@@ -101,12 +97,12 @@ bootstrap-test262:
|
||||
cd build/test262 && git checkout $(TEST262_COMMIT)
|
||||
|
||||
test-test262:
|
||||
node scripts/tests/test262/run_babylon_test262.js
|
||||
node scripts/tests/test262/run_babel_parser_test262.js
|
||||
|
||||
test-test262-ci: bootstrap test-test262
|
||||
|
||||
test-test262-update-whitelist:
|
||||
node scripts/tests/test262/run_babylon_test262.js --update-whitelist
|
||||
node scripts/tests/test262/run_babel_parser_test262.js --update-whitelist
|
||||
|
||||
publish:
|
||||
git pull --rebase
|
||||
@@ -134,6 +130,7 @@ clean-lib:
|
||||
clean-all:
|
||||
rm -rf node_modules
|
||||
rm -rf package-lock.json
|
||||
rm -rf .changelog
|
||||
|
||||
$(foreach source, $(SOURCES), \
|
||||
$(call clean-source-all, $(source)))
|
||||
|
||||
@@ -68,11 +68,6 @@ Become a sponsor and get your logo on our README on Github with a link to your s
|
||||
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://www.patreon.com/henryzhu)]
|
||||
|
||||
## Gold
|
||||
|
||||
<a href="https://vueschool.io/?babel" target="_blank"><img src="http://new.babeljs.io/img/sponsors/vueschool.png" height="64"></a>
|
||||
<a href="https://devrant.com/?babel" target="_blank"><img src="http://new.babeljs.io/img/sponsors/devRant.png" height="64"></a>
|
||||
|
||||
## Bronze
|
||||
|
||||
<a href="http://teamextension.io/" target="_blank"><img src="https://teamextension.io/dist/img/logo/te-logo-compact.png" height="64"></a>
|
||||
|
||||
97
babel.config.js
Normal file
97
babel.config.js
Normal file
@@ -0,0 +1,97 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function(api) {
|
||||
const env = api.env();
|
||||
|
||||
const includeCoverage = process.env.BABEL_COVERAGE === "true";
|
||||
|
||||
const envOpts = {
|
||||
loose: true,
|
||||
modules: false,
|
||||
exclude: ["transform-typeof-symbol"],
|
||||
};
|
||||
|
||||
let convertESM = true;
|
||||
let ignoreLib = true;
|
||||
|
||||
switch (env) {
|
||||
// Configs used during bundling builds.
|
||||
case "babel-parser":
|
||||
case "standalone":
|
||||
convertESM = false;
|
||||
ignoreLib = false;
|
||||
break;
|
||||
case "production":
|
||||
// Config during builds before publish.
|
||||
envOpts.targets = {
|
||||
node: "6.9",
|
||||
};
|
||||
break;
|
||||
case "development":
|
||||
envOpts.debug = true;
|
||||
envOpts.targets = {
|
||||
node: "current",
|
||||
};
|
||||
break;
|
||||
case "test":
|
||||
envOpts.targets = {
|
||||
node: "current",
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
const config = {
|
||||
comments: false,
|
||||
ignore: [
|
||||
// These may not be strictly necessary with the newly-limited scope of
|
||||
// babelrc searching, but including them for now because we had them
|
||||
// in our .babelignore before.
|
||||
"packages/*/test/fixtures",
|
||||
ignoreLib ? "packages/*/lib" : null,
|
||||
"packages/babel-standalone/babel.js",
|
||||
"packages/babel-preset-env-standalone/babel-preset-env.js",
|
||||
].filter(Boolean),
|
||||
presets: [["@babel/env", envOpts]],
|
||||
plugins: [
|
||||
// TODO: Use @babel/preset-flow when
|
||||
// https://github.com/babel/babel/issues/7233 is fixed
|
||||
"@babel/plugin-transform-flow-strip-types",
|
||||
["@babel/proposal-class-properties", { loose: true }],
|
||||
"@babel/proposal-export-namespace-from",
|
||||
"@babel/proposal-numeric-separator",
|
||||
[
|
||||
"@babel/proposal-object-rest-spread",
|
||||
{ useBuiltIns: true, loose: true },
|
||||
],
|
||||
|
||||
// Explicitly use the lazy version of CommonJS modules.
|
||||
convertESM ? ["@babel/transform-modules-commonjs", { lazy: true }] : null,
|
||||
].filter(Boolean),
|
||||
overrides: [
|
||||
{
|
||||
test: "packages/babel-parser",
|
||||
plugins: [
|
||||
"babel-plugin-transform-charcodes",
|
||||
["@babel/transform-for-of", { assumeArray: true }],
|
||||
],
|
||||
},
|
||||
{
|
||||
test: "./packages/babel-register",
|
||||
plugins: [
|
||||
// Override the root options to disable lazy imports for babel-register
|
||||
// because otherwise the require hook will try to lazy-import things
|
||||
// leading to dependency cycles.
|
||||
convertESM ? "@babel/transform-modules-commonjs" : null,
|
||||
].filter(Boolean),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// we need to do this as long as we do not test everything from source
|
||||
if (includeCoverage) {
|
||||
config.auxiliaryCommentBefore = "istanbul ignore next";
|
||||
config.plugins.push("babel-plugin-istanbul");
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
src
|
||||
test
|
||||
*.log
|
||||
@@ -0,0 +1,57 @@
|
||||
# @babel/plugin-codemod-object-assign-to-object-spread
|
||||
|
||||
Transforms old code that uses `Object.assign` with an Object Literal as
|
||||
the first param to use Object Spread syntax.
|
||||
|
||||
## Examples
|
||||
|
||||
```js
|
||||
const obj = Object.assign({
|
||||
test1: 1,
|
||||
}, other, {
|
||||
test2: 2,
|
||||
}, other2);
|
||||
```
|
||||
|
||||
Is transformed to:
|
||||
|
||||
```js
|
||||
const obj = {
|
||||
test1: 1,
|
||||
...other,
|
||||
test2: 2,
|
||||
...other2,
|
||||
};
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install --save-dev @babel/plugin-codemod-object-assign-to-object-spread
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Via `.babelrc` (Recommended)
|
||||
|
||||
**.babelrc**
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["@babel/plugin-codemod-object-assign-to-object-spread"]
|
||||
}
|
||||
```
|
||||
|
||||
### Via CLI
|
||||
|
||||
```sh
|
||||
babel --plugins @babel/plugin-codemod-object-assign-to-object-spread script.js
|
||||
```
|
||||
|
||||
### Via Node API
|
||||
|
||||
```javascript
|
||||
require("@babel/core").transform("code", {
|
||||
plugins: ["@babel/plugin-codemod-object-assign-to-object-spread"]
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "@babel/plugin-codemod-object-assign-to-object-spread",
|
||||
"version": "7.0.0-beta.50",
|
||||
"description": "Transforms Object.assign into object spread syntax",
|
||||
"repository": "https://github.com/babel/babel/tree/master/codemods/babel-plugin-codemod-object-assign-to-object-spread",
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
"keywords": [
|
||||
"@babel/codemod",
|
||||
"@babel/plugin"
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.50"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "7.0.0-beta.49"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.0.0-beta.50",
|
||||
"@babel/helper-plugin-test-runner": "7.0.0-beta.50"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import syntaxObjectRestSpread from "@babel/plugin-syntax-object-rest-spread";
|
||||
|
||||
export default function({ types: t }) {
|
||||
return {
|
||||
inherits: syntaxObjectRestSpread,
|
||||
|
||||
visitor: {
|
||||
CallExpression(path) {
|
||||
if (!path.get("callee").matchesPattern("Object.assign")) return;
|
||||
|
||||
const args = path.get("arguments");
|
||||
if (args.length === 0) return;
|
||||
|
||||
const [objPath] = args;
|
||||
if (!objPath.isObjectExpression()) return;
|
||||
|
||||
const obj = objPath.node;
|
||||
const { properties } = obj;
|
||||
|
||||
for (let i = 1; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
const { node } = arg;
|
||||
|
||||
if (arg.isObjectExpression()) {
|
||||
properties.push(...node.properties);
|
||||
} else {
|
||||
properties.push(t.spreadElement(node));
|
||||
}
|
||||
}
|
||||
|
||||
path.replaceWith(obj);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Object.assign({test: 1}, {test: 2});
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["../../../../lib"]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
({
|
||||
test: 1,
|
||||
test: 2
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
Object.assign({test: 1}, test2, {test: 2}, test3);
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["../../../../lib"]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
({
|
||||
test: 1,
|
||||
...test2,
|
||||
test: 2,
|
||||
...test3
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
Object.assign(test);
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["../../../../lib"]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Object.assign(test);
|
||||
@@ -0,0 +1 @@
|
||||
Object.assign({test: 1});
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["../../../../lib"]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
({
|
||||
test: 1
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
import runner from "@babel/helper-plugin-test-runner";
|
||||
|
||||
runner(__dirname);
|
||||
@@ -1,21 +1,22 @@
|
||||
{
|
||||
"name": "@babel/plugin-codemod-optional-catch-binding",
|
||||
"version": "7.0.0-beta.46",
|
||||
"version": "7.0.0-beta.50",
|
||||
"description": "Remove unused catch bindings",
|
||||
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-remove-unused-catch-binding",
|
||||
"repository": "https://github.com/babel/babel/tree/master/codemods/babel-plugin-codemod-remove-unused-catch-binding",
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
"keywords": [
|
||||
"@babel/codemod",
|
||||
"@babel/plugin"
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.46"
|
||||
"@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.50"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "7.0.0-beta.46"
|
||||
"@babel/core": "7.0.0-beta.49"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.0.0-beta.46",
|
||||
"@babel/helper-plugin-test-runner": "7.0.0-beta.46"
|
||||
"@babel/core": "7.0.0-beta.50",
|
||||
"@babel/helper-plugin-test-runner": "7.0.0-beta.50"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import syntaxOptionalCatchBinding from "@babel/plugin-syntax-optional-catch-binding";
|
||||
import { types as t } from "@babel/core";
|
||||
|
||||
export default function() {
|
||||
export default function({ types: t }) {
|
||||
return {
|
||||
inherits: syntaxOptionalCatchBinding,
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
The [AST specification](https://github.com/babel/babel/blob/master/packages/babylon/ast/spec.md) has been moved to the Babylon package, `packages/babylon`.
|
||||
The [AST specification](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md) has been moved to the babel parser package, `packages/babel-parser`.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"lerna": "2.0.0-rc.4",
|
||||
"version": "7.0.0-beta.46",
|
||||
"lerna": "2.11.0",
|
||||
"version": "7.0.0-beta.50",
|
||||
"changelog": {
|
||||
"repo": "babel/babel",
|
||||
"cacheDir": ".changelog",
|
||||
"labels": {
|
||||
"PR: Spec Compliancy :eyeglasses:": ":eyeglasses: Spec Compliancy",
|
||||
"PR: Breaking Change :boom:": ":boom: Breaking Change",
|
||||
@@ -13,7 +14,6 @@
|
||||
"PR: Internal :house:": ":house: Internal"
|
||||
}
|
||||
},
|
||||
"cacheDir": ".changelog",
|
||||
"commands": {
|
||||
"publish": {
|
||||
"ignore": [
|
||||
|
||||
@@ -26,22 +26,124 @@ declare module "lodash/defaults" {
|
||||
|
||||
declare module "lodash/clone" {
|
||||
declare export default <T>(obj: T) => T;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "lodash/merge" {
|
||||
declare export default <T: Object>(T, Object) => T;
|
||||
}
|
||||
|
||||
declare module "convert-source-map" {
|
||||
declare module "source-map" {
|
||||
declare export type SourceMap = {
|
||||
version: 3,
|
||||
file: ?string,
|
||||
sourceRoot: ?string,
|
||||
sources: [?string],
|
||||
sourcesContent: [?string],
|
||||
names: [?string],
|
||||
mappings: string,
|
||||
};
|
||||
|
||||
declare module.exports: {
|
||||
SourceMapConsumer: typeof SourceMapConsumer,
|
||||
SourceMapGenerator: typeof SourceMapGenerator,
|
||||
}
|
||||
|
||||
declare class SourceMapConsumer {
|
||||
static GENERATED_ORDER: 1;
|
||||
static ORIGINAL_ORDER: 2;
|
||||
|
||||
file: string | null;
|
||||
sourceRoot: string | null;
|
||||
sources: Array<string>;
|
||||
|
||||
constructor(?SourceMap): this;
|
||||
|
||||
computeColumnSpans(): string;
|
||||
originalPositionFor({
|
||||
line: number,
|
||||
column: number,
|
||||
}): {|
|
||||
source: string,
|
||||
line: number,
|
||||
column: number,
|
||||
name: string | null
|
||||
|} | {|
|
||||
source: null,
|
||||
line: null,
|
||||
column: null,
|
||||
name: null
|
||||
|};
|
||||
|
||||
generatedPositionFor({
|
||||
source: string,
|
||||
line: number,
|
||||
column: number,
|
||||
}): {|
|
||||
line: number,
|
||||
column: number,
|
||||
lastColumn: number | null | void,
|
||||
|} | {|
|
||||
line: null,
|
||||
column: null,
|
||||
lastColumn: null | void,
|
||||
|};
|
||||
|
||||
allGeneratedPositionsFor({
|
||||
source: string,
|
||||
line: number,
|
||||
column: number,
|
||||
}): Array<{|
|
||||
line: number,
|
||||
column: number,
|
||||
lastColumn: number,
|
||||
|}>;
|
||||
|
||||
sourceContentFor(string, boolean | void): string | null;
|
||||
|
||||
eachMapping(
|
||||
({|
|
||||
generatedLine: number,
|
||||
generatedColumn: number,
|
||||
source: string,
|
||||
originalLine: number,
|
||||
originalColumn: number,
|
||||
name: string | null,
|
||||
|} | {|
|
||||
generatedLine: number,
|
||||
generatedColumn: number,
|
||||
source: null,
|
||||
originalLine: null,
|
||||
originalColumn: null,
|
||||
name: null,
|
||||
|}) => mixed,
|
||||
context: mixed,
|
||||
order: ?(1 | 2),
|
||||
): void;
|
||||
}
|
||||
|
||||
declare class SourceMapGenerator {
|
||||
constructor(?{
|
||||
file?: string | null,
|
||||
sourceRoot?: string | null,
|
||||
skipValidation?: boolean | null,
|
||||
}): this;
|
||||
|
||||
addMapping({
|
||||
generated: {
|
||||
line: number,
|
||||
column: number,
|
||||
}
|
||||
}): void;
|
||||
|
||||
setSourceContent(string, string): void;
|
||||
|
||||
toJSON(): SourceMap;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "convert-source-map" {
|
||||
import type { SourceMap } from "source-map";
|
||||
|
||||
declare class Converter {
|
||||
toJSON(): string;
|
||||
toBase64(): string;
|
||||
@@ -64,3 +166,9 @@ declare module "convert-source-map" {
|
||||
generateMapFileComment(path: string, options?: ?{ multiline: boolean }): string,
|
||||
};
|
||||
}
|
||||
|
||||
declare module "js-levenshtein" {
|
||||
declare module.exports: {
|
||||
(string, string): number,
|
||||
};
|
||||
}
|
||||
|
||||
41
package.json
41
package.json
@@ -10,19 +10,18 @@
|
||||
"test": "make test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.0.0-beta.44",
|
||||
"@babel/core": "7.0.0-beta.44",
|
||||
"@babel/plugin-transform-modules-commonjs": "7.0.0-beta.44",
|
||||
"@babel/preset-env": "7.0.0-beta.44",
|
||||
"@babel/preset-flow": "7.0.0-beta.44",
|
||||
"@babel/preset-stage-0": "7.0.0-beta.44",
|
||||
"@babel/register": "7.0.0-beta.44",
|
||||
"@babel/cli": "7.0.0-beta.48",
|
||||
"@babel/core": "7.0.0-beta.48",
|
||||
"@babel/plugin-transform-modules-commonjs": "7.0.0-beta.48",
|
||||
"@babel/preset-env": "7.0.0-beta.48",
|
||||
"@babel/preset-flow": "7.0.0-beta.48",
|
||||
"@babel/preset-stage-0": "7.0.0-beta.48",
|
||||
"@babel/register": "7.0.0-beta.48",
|
||||
"babel-core": "^7.0.0-0",
|
||||
"babel-eslint": "^8.0.1",
|
||||
"babel-jest": "^22.4.1",
|
||||
"babel-loader": "8.0.0-beta.0",
|
||||
"babel-plugin-transform-charcodes": "^0.1.0",
|
||||
"babylon": "7.0.0-beta.44",
|
||||
"browserify": "^13.1.1",
|
||||
"bundle-collapser": "^1.2.1",
|
||||
"chalk": "^2.3.2",
|
||||
@@ -32,10 +31,10 @@
|
||||
"eslint": "^4.18.2",
|
||||
"eslint-config-babel": "^7.0.2",
|
||||
"eslint-plugin-flowtype": "^2.20.0",
|
||||
"eslint-plugin-prettier": "^2.5.0",
|
||||
"flow-bin": "^0.66.0",
|
||||
"eslint-plugin-prettier": "^2.6.0",
|
||||
"flow-bin": "^0.73.0",
|
||||
"graceful-fs": "^4.1.11",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-babel": "^8.0.0-beta.2",
|
||||
"gulp-filter": "^5.1.0",
|
||||
"gulp-newer": "^1.0.0",
|
||||
@@ -43,22 +42,22 @@
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-uglify": "^3.0.0",
|
||||
"gulp-util": "^3.0.7",
|
||||
"gulp-watch": "^4.3.5",
|
||||
"gulp-watch": "^5.0.0",
|
||||
"husky": "^0.14.3",
|
||||
"jest": "^22.4.2",
|
||||
"lerna": "2.0.0",
|
||||
"lerna": "^2.11.0",
|
||||
"lerna-changelog": "^0.5.0",
|
||||
"lint-staged": "^6.0.1",
|
||||
"lodash": "^4.2.0",
|
||||
"lodash": "^4.17.5",
|
||||
"merge-stream": "^1.0.1",
|
||||
"output-file-sync": "^2.0.0",
|
||||
"prettier": "1.11.1",
|
||||
"prettier": "1.13.2",
|
||||
"pump": "^1.0.2",
|
||||
"rimraf": "^2.4.3",
|
||||
"rollup-plugin-babel": "^4.0.0-beta.0",
|
||||
"rollup-plugin-node-resolve": "^3.0.2",
|
||||
"rollup-stream": "^1.24.1",
|
||||
"test262-stream": "^1.1.0",
|
||||
"test262-stream": "^1.2.0",
|
||||
"through2": "^2.0.0",
|
||||
"uglify-js": "^2.4.16",
|
||||
"vinyl-buffer": "^1.0.1",
|
||||
@@ -68,7 +67,7 @@
|
||||
"webpack-stream": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.x <= 9.x",
|
||||
"node": ">= 6.9.0 <= 11.0.0-0",
|
||||
"npm": ">= 2.x <= 5.x",
|
||||
"yarn": ">=0.27.5 || >=1.0.0-20170811"
|
||||
},
|
||||
@@ -89,7 +88,7 @@
|
||||
"/node_modules/",
|
||||
"/test/fixtures/",
|
||||
"/test/debug-fixtures/",
|
||||
"/babylon/test/expressions/",
|
||||
"/babel-parser/test/expressions/",
|
||||
"/test/tmp/",
|
||||
"/test/__data__/",
|
||||
"/test/helpers/",
|
||||
@@ -106,6 +105,12 @@
|
||||
"/test/(fixtures|tmp|__data__)/",
|
||||
"<rootDir>/(packages|codemods)/[^/]+/lib/"
|
||||
],
|
||||
"coveragePathIgnorePatterns": [
|
||||
"/node_modules/",
|
||||
"<rootDir>/packages/babel-standalone/babel(\\.min)?\\.js",
|
||||
"<rootDir>/packages/babel-preset-env-standalone/babel-preset-env(\\.min)?\\.js",
|
||||
"/test/(fixtures|tmp|__data__)/"
|
||||
],
|
||||
"modulePathIgnorePatterns": [
|
||||
"/test/fixtures/",
|
||||
"/test/tmp/",
|
||||
|
||||
@@ -14,21 +14,21 @@ A monorepo, muhahahahahaha. See the [monorepo design doc](/doc/design/monorepo.m
|
||||
| Package | Version | Dependencies |
|
||||
|--------|-------|------------|
|
||||
| [`@babel/core`](/packages/babel-core) | [](https://www.npmjs.com/package/@babel/core) | [](https://david-dm.org/babel/babel?path=packages/babel-core) |
|
||||
| [`babylon`](/packages/babylon) | [](https://www.npmjs.com/package/babylon) | [](https://david-dm.org/babel/babel?path=packages/babylon) |
|
||||
| [`@babel/parser`](/packages/@babel/parser) | [](https://www.npmjs.com/package/@babel/parser) | [](https://david-dm.org/babel/babel?path=packages/babel-parser) |
|
||||
| [`@babel/traverse`](/packages/babel-traverse) | [](https://www.npmjs.com/package/@babel/traverse) | [](https://david-dm.org/babel/babel?path=packages/babel-traverse) |
|
||||
| [`@babel/generator`](/packages/babel-generator) | [](https://www.npmjs.com/package/@babel/generator) | [](https://david-dm.org/babel/babel?path=packages/babel-generator) |
|
||||
|
||||
[`@babel/core`](/packages/babel-core) is the Babel compiler itself; it exposes the `babel.transform` method, where `transformedCode = transform(src).code`.
|
||||
|
||||
The compiler can be broken down into 3 parts:
|
||||
- The parser: [`babylon`](/packages/babylon)
|
||||
- The parser: [`@babel/parser`](/packages/babel-parser)
|
||||
- The transformer[s]: All the plugins/presets
|
||||
- These all use [`@babel/traverse`](/packages/babel-traverse) to traverse through the AST
|
||||
- The generator: [`@babel/generator`](/packages/babel-generator)
|
||||
|
||||
The flow goes like this:
|
||||
|
||||
input string -> `babylon` parser -> `AST` -> transformer[s] -> `AST` -> `@babel/generator` -> output string
|
||||
input string -> `@babel/parser` parser -> `AST` -> transformer[s] -> `AST` -> `@babel/generator` -> output string
|
||||
|
||||
Check out the [`babel-handbook`](https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md#introduction) for more information on this.
|
||||
|
||||
|
||||
@@ -2,20 +2,18 @@
|
||||
|
||||
> Babel command line.
|
||||
|
||||
In addition, various entry point scripts live in the top-level package at `@babel/cli/bin`.
|
||||
|
||||
There is a shell-executable utility script, `babel-external-helpers.js`, and the main Babel cli script, `babel.js`.
|
||||
See our website [@babel/cli](https://new.babeljs.io/docs/en/next/babel-cli.html) for more information or the [issues](https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A%20cli%22+is%3Aopen) associated with this package.
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
npm install --save-dev @babel/core @babel/cli
|
||||
```
|
||||
|
||||
## Usage
|
||||
Using npm:
|
||||
|
||||
```sh
|
||||
babel script.js
|
||||
npm install --save @babel/cli
|
||||
```
|
||||
|
||||
For more in depth documentation see: http://babeljs.io/docs/usage/cli/
|
||||
or using yarn:
|
||||
|
||||
```sh
|
||||
yarn add --save @babel/cli
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@babel/cli",
|
||||
"version": "7.0.0-beta.46",
|
||||
"version": "7.0.0-beta.50",
|
||||
"description": "Babel command line.",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
@@ -20,20 +20,20 @@
|
||||
"convert-source-map": "^1.1.0",
|
||||
"fs-readdir-recursive": "^1.0.0",
|
||||
"glob": "^7.0.0",
|
||||
"lodash": "^4.2.0",
|
||||
"lodash": "^4.17.5",
|
||||
"output-file-sync": "^2.0.0",
|
||||
"slash": "^1.0.0",
|
||||
"source-map": "^0.5.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"chokidar": "^1.6.1"
|
||||
"chokidar": "^2.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "7.0.0-beta.46"
|
||||
"@babel/core": "7.0.0-beta.49"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.0.0-beta.46",
|
||||
"@babel/helper-fixtures": "7.0.0-beta.46"
|
||||
"@babel/core": "7.0.0-beta.50",
|
||||
"@babel/helper-fixtures": "7.0.0-beta.50"
|
||||
},
|
||||
"bin": {
|
||||
"babel": "./bin/babel.js",
|
||||
|
||||
@@ -6,165 +6,147 @@ import fs from "fs";
|
||||
|
||||
import * as util from "./util";
|
||||
|
||||
let compiledFiles = 0;
|
||||
export default async function({ cliOptions, babelOptions }) {
|
||||
const filenames = cliOptions.filenames;
|
||||
|
||||
export default function(commander, filenames, opts) {
|
||||
function write(src, relative, base, callback) {
|
||||
if (typeof base === "function") {
|
||||
callback = base;
|
||||
base = undefined;
|
||||
}
|
||||
if (!util.isCompilableExtension(relative, commander.extensions)) {
|
||||
return process.nextTick(callback);
|
||||
async function write(src, base) {
|
||||
let relative = path.relative(base, src);
|
||||
|
||||
if (!util.isCompilableExtension(relative, cliOptions.extensions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// remove extension and then append back on .js
|
||||
relative = util.adjustRelative(relative, commander.keepFileExtension);
|
||||
relative = util.adjustRelative(relative, cliOptions.keepFileExtension);
|
||||
|
||||
const dest = getDest(commander, relative, base);
|
||||
const dest = getDest(relative, base);
|
||||
|
||||
util.compile(
|
||||
src,
|
||||
defaults(
|
||||
{
|
||||
sourceFileName: slash(path.relative(dest + "/..", src)),
|
||||
},
|
||||
opts,
|
||||
),
|
||||
function(err, res) {
|
||||
if (err) return callback(err);
|
||||
if (!res) return callback();
|
||||
try {
|
||||
const res = await util.compile(
|
||||
src,
|
||||
defaults(
|
||||
{
|
||||
sourceFileName: slash(path.relative(dest + "/..", src)),
|
||||
},
|
||||
babelOptions,
|
||||
),
|
||||
);
|
||||
|
||||
// we've requested explicit sourcemaps to be written to disk
|
||||
if (
|
||||
res.map &&
|
||||
commander.sourceMaps &&
|
||||
commander.sourceMaps !== "inline"
|
||||
) {
|
||||
const mapLoc = dest + ".map";
|
||||
res.code = util.addSourceMappingUrl(res.code, mapLoc);
|
||||
res.map.file = path.basename(relative);
|
||||
outputFileSync(mapLoc, JSON.stringify(res.map));
|
||||
}
|
||||
if (!res) return false;
|
||||
|
||||
outputFileSync(dest, res.code);
|
||||
util.chmod(src, dest);
|
||||
// we've requested explicit sourcemaps to be written to disk
|
||||
if (
|
||||
res.map &&
|
||||
babelOptions.sourceMaps &&
|
||||
babelOptions.sourceMaps !== "inline"
|
||||
) {
|
||||
const mapLoc = dest + ".map";
|
||||
res.code = util.addSourceMappingUrl(res.code, mapLoc);
|
||||
res.map.file = path.basename(relative);
|
||||
outputFileSync(mapLoc, JSON.stringify(res.map));
|
||||
}
|
||||
|
||||
compiledFiles += 1;
|
||||
outputFileSync(dest, res.code);
|
||||
util.chmod(src, dest);
|
||||
|
||||
util.log(src + " -> " + dest);
|
||||
return callback(null, true);
|
||||
},
|
||||
);
|
||||
if (cliOptions.verbose) {
|
||||
console.log(src + " -> " + dest);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
if (cliOptions.watch) {
|
||||
console.error(err);
|
||||
return false;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function getDest(commander, filename, base) {
|
||||
if (commander.relative) return path.join(base, commander.outDir, filename);
|
||||
return path.join(commander.outDir, filename);
|
||||
function getDest(filename, base) {
|
||||
if (cliOptions.relative) {
|
||||
return path.join(base, cliOptions.outDir, filename);
|
||||
}
|
||||
return path.join(cliOptions.outDir, filename);
|
||||
}
|
||||
|
||||
function outputDestFolder(outDir) {
|
||||
const outDirPath = path.resolve(outDir);
|
||||
if (!fs.existsSync(outDirPath)) {
|
||||
|
||||
try {
|
||||
fs.mkdirSync(outDirPath);
|
||||
} catch (err) {
|
||||
// Testing for the directory and then creating it can lead to race
|
||||
// conditions if there are multiple processes, so we try to create it
|
||||
// and bail if it already exists.
|
||||
if (err.code !== "EEXIST") throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function handleFile(src, filename, base, callback) {
|
||||
if (typeof base === "function") {
|
||||
callback = base;
|
||||
base = undefined;
|
||||
async function handleFile(src, base) {
|
||||
const written = await write(src, base);
|
||||
|
||||
if (!written && cliOptions.copyFiles) {
|
||||
const filename = path.relative(base, src);
|
||||
const dest = getDest(filename, base);
|
||||
outputFileSync(dest, fs.readFileSync(src));
|
||||
util.chmod(src, dest);
|
||||
}
|
||||
|
||||
write(src, filename, base, function(err, res) {
|
||||
if (err) return callback(err);
|
||||
if (!res && commander.copyFiles) {
|
||||
const dest = getDest(commander, filename, base);
|
||||
outputFileSync(dest, fs.readFileSync(src));
|
||||
util.chmod(src, dest);
|
||||
}
|
||||
|
||||
return callback();
|
||||
});
|
||||
return written;
|
||||
}
|
||||
|
||||
function sequentialHandleFile(files, dirname, index, callback) {
|
||||
if (files.length === 0) {
|
||||
outputDestFolder(commander.outDir);
|
||||
return;
|
||||
}
|
||||
async function handle(filenameOrDir) {
|
||||
if (!fs.existsSync(filenameOrDir)) return 0;
|
||||
|
||||
if (typeof index === "function") {
|
||||
callback = index;
|
||||
index = 0;
|
||||
}
|
||||
const stat = fs.statSync(filenameOrDir);
|
||||
|
||||
const filename = files[index];
|
||||
const src = path.join(dirname, filename);
|
||||
if (stat.isDirectory(filenameOrDir)) {
|
||||
const dirname = filenameOrDir;
|
||||
|
||||
handleFile(src, filename, dirname, function(err) {
|
||||
if (err) return callback(err);
|
||||
index++;
|
||||
if (index !== files.length) {
|
||||
sequentialHandleFile(files, dirname, index, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
let count = 0;
|
||||
|
||||
function handle(filename, callback) {
|
||||
if (!fs.existsSync(filename)) return;
|
||||
const files = util.readdir(dirname, cliOptions.includeDotfiles);
|
||||
for (const filename of files) {
|
||||
const src = path.join(dirname, filename);
|
||||
|
||||
const stat = fs.statSync(filename);
|
||||
|
||||
if (stat.isDirectory(filename)) {
|
||||
const dirname = filename;
|
||||
|
||||
if (commander.deleteDirOnStart) {
|
||||
util.deleteDir(commander.outDir);
|
||||
const written = await handleFile(src, dirname);
|
||||
if (written) count += 1;
|
||||
}
|
||||
|
||||
const files = util.readdir(dirname, commander.includeDotfiles);
|
||||
sequentialHandleFile(files, dirname, callback);
|
||||
return count;
|
||||
} else {
|
||||
write(
|
||||
filename,
|
||||
path.basename(filename),
|
||||
path.dirname(filename),
|
||||
callback,
|
||||
);
|
||||
const filename = filenameOrDir;
|
||||
const written = await handleFile(filename, path.dirname(filename));
|
||||
|
||||
return written ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
function sequentialHandle(filenames, index = 0) {
|
||||
const filename = filenames[index];
|
||||
if (!cliOptions.skipInitialBuild) {
|
||||
if (cliOptions.deleteDirOnStart) {
|
||||
util.deleteDir(cliOptions.outDir);
|
||||
}
|
||||
|
||||
handle(filename, function(err) {
|
||||
if (err) throw new Error(err);
|
||||
index++;
|
||||
if (index !== filenames.length) {
|
||||
sequentialHandle(filenames, index);
|
||||
} else {
|
||||
util.log(
|
||||
`🎉 Successfully compiled ${compiledFiles} ${
|
||||
compiledFiles > 1 ? "files" : "file"
|
||||
} with Babel.`,
|
||||
true,
|
||||
);
|
||||
}
|
||||
});
|
||||
outputDestFolder(cliOptions.outDir);
|
||||
|
||||
let compiledFiles = 0;
|
||||
for (const filename of cliOptions.filenames) {
|
||||
compiledFiles += await handle(filename);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`🎉 Successfully compiled ${compiledFiles} ${
|
||||
compiledFiles !== 1 ? "files" : "file"
|
||||
} with Babel.`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!commander.skipInitialBuild) {
|
||||
sequentialHandle(filenames);
|
||||
}
|
||||
|
||||
if (commander.watch) {
|
||||
if (cliOptions.watch) {
|
||||
const chokidar = util.requireChokidar();
|
||||
|
||||
filenames.forEach(function(dirname) {
|
||||
const watcher = chokidar.watch(dirname, {
|
||||
filenames.forEach(function(filenameOrDir) {
|
||||
const watcher = chokidar.watch(filenameOrDir, {
|
||||
persistent: true,
|
||||
ignoreInitial: true,
|
||||
awaitWriteFinish: {
|
||||
@@ -175,14 +157,14 @@ export default function(commander, filenames, opts) {
|
||||
|
||||
["add", "change"].forEach(function(type) {
|
||||
watcher.on(type, function(filename) {
|
||||
const relative = path.relative(dirname, filename) || filename;
|
||||
try {
|
||||
handleFile(filename, relative, function(err) {
|
||||
if (err) throw err;
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err.stack);
|
||||
}
|
||||
handleFile(
|
||||
filename,
|
||||
filename === filenameOrDir
|
||||
? path.dirname(filenameOrDir)
|
||||
: filenameOrDir,
|
||||
).catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,26 +7,22 @@ import fs from "fs";
|
||||
|
||||
import * as util from "./util";
|
||||
|
||||
export default function(commander, filenames, opts) {
|
||||
if (commander.sourceMaps === "inline") {
|
||||
opts.sourceMaps = true;
|
||||
}
|
||||
|
||||
let results = [];
|
||||
|
||||
const buildResult = function() {
|
||||
export default async function({ cliOptions, babelOptions }) {
|
||||
function buildResult(fileResults) {
|
||||
const map = new sourceMap.SourceMapGenerator({
|
||||
file:
|
||||
commander.sourceMapTarget ||
|
||||
path.basename(commander.outFile || "") ||
|
||||
cliOptions.sourceMapTarget ||
|
||||
path.basename(cliOptions.outFile || "") ||
|
||||
"stdout",
|
||||
sourceRoot: opts.sourceRoot,
|
||||
sourceRoot: babelOptions.sourceRoot,
|
||||
});
|
||||
|
||||
let code = "";
|
||||
let offset = 0;
|
||||
|
||||
results.forEach(function(result) {
|
||||
for (const result of fileResults) {
|
||||
if (!result) continue;
|
||||
|
||||
code += result.code + "\n";
|
||||
|
||||
if (result.map) {
|
||||
@@ -61,13 +57,13 @@ export default function(commander, filenames, opts) {
|
||||
|
||||
offset = code.split("\n").length - 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// add the inline sourcemap comment if we've either explicitly asked for inline source
|
||||
// maps, or we've requested them without any output file
|
||||
if (
|
||||
commander.sourceMaps === "inline" ||
|
||||
(!commander.outFile && commander.sourceMaps)
|
||||
babelOptions.sourceMaps === "inline" ||
|
||||
(!cliOptions.outFile && babelOptions.sourceMaps)
|
||||
) {
|
||||
code += "\n" + convertSourceMap.fromObject(map).toComment();
|
||||
}
|
||||
@@ -76,57 +72,62 @@ export default function(commander, filenames, opts) {
|
||||
map: map,
|
||||
code: code,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const output = function() {
|
||||
const result = buildResult();
|
||||
function output(fileResults) {
|
||||
const result = buildResult(fileResults);
|
||||
|
||||
if (commander.outFile) {
|
||||
if (cliOptions.outFile) {
|
||||
// we've requested for a sourcemap to be written to disk
|
||||
if (commander.sourceMaps && commander.sourceMaps !== "inline") {
|
||||
const mapLoc = commander.outFile + ".map";
|
||||
if (babelOptions.sourceMaps && babelOptions.sourceMaps !== "inline") {
|
||||
const mapLoc = cliOptions.outFile + ".map";
|
||||
result.code = util.addSourceMappingUrl(result.code, mapLoc);
|
||||
fs.writeFileSync(mapLoc, JSON.stringify(result.map));
|
||||
}
|
||||
|
||||
fs.writeFileSync(commander.outFile, result.code);
|
||||
fs.writeFileSync(cliOptions.outFile, result.code);
|
||||
} else {
|
||||
process.stdout.write(result.code + "\n");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const stdin = function() {
|
||||
let code = "";
|
||||
function readStdin() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let code = "";
|
||||
|
||||
process.stdin.setEncoding("utf8");
|
||||
process.stdin.setEncoding("utf8");
|
||||
|
||||
process.stdin.on("readable", function() {
|
||||
const chunk = process.stdin.read();
|
||||
if (chunk !== null) code += chunk;
|
||||
process.stdin.on("readable", function() {
|
||||
const chunk = process.stdin.read();
|
||||
if (chunk !== null) code += chunk;
|
||||
});
|
||||
|
||||
process.stdin.on("end", function() {
|
||||
resolve(code);
|
||||
});
|
||||
process.stdin.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
process.stdin.on("end", function() {
|
||||
util.transform(
|
||||
commander.filename,
|
||||
code,
|
||||
defaults(
|
||||
{
|
||||
sourceFileName: "stdin",
|
||||
},
|
||||
opts,
|
||||
),
|
||||
function(err, res) {
|
||||
if (err) throw err;
|
||||
results.push(res);
|
||||
output();
|
||||
async function stdin() {
|
||||
const code = await readStdin();
|
||||
|
||||
const res = await util.transform(
|
||||
cliOptions.filename,
|
||||
code,
|
||||
defaults(
|
||||
{
|
||||
sourceFileName: "stdin",
|
||||
},
|
||||
);
|
||||
});
|
||||
};
|
||||
babelOptions,
|
||||
),
|
||||
);
|
||||
|
||||
const walk = function() {
|
||||
output([res]);
|
||||
}
|
||||
|
||||
async function walk(filenames) {
|
||||
const _filenames = [];
|
||||
results = [];
|
||||
|
||||
filenames.forEach(function(filename) {
|
||||
if (!fs.existsSync(filename)) return;
|
||||
@@ -136,7 +137,7 @@ export default function(commander, filenames, opts) {
|
||||
const dirname = filename;
|
||||
|
||||
util
|
||||
.readdirForCompilable(filename, commander.includeDotfiles)
|
||||
.readdirForCompilable(filename, cliOptions.includeDotfiles)
|
||||
.forEach(function(filename) {
|
||||
_filenames.push(path.join(dirname, filename));
|
||||
});
|
||||
@@ -145,46 +146,54 @@ export default function(commander, filenames, opts) {
|
||||
}
|
||||
});
|
||||
|
||||
let filesProcessed = 0;
|
||||
const results = await Promise.all(
|
||||
_filenames.map(async function(filename) {
|
||||
let sourceFilename = filename;
|
||||
if (cliOptions.outFile) {
|
||||
sourceFilename = path.relative(
|
||||
path.dirname(cliOptions.outFile),
|
||||
sourceFilename,
|
||||
);
|
||||
}
|
||||
sourceFilename = slash(sourceFilename);
|
||||
|
||||
_filenames.forEach(function(filename, index) {
|
||||
let sourceFilename = filename;
|
||||
if (commander.outFile) {
|
||||
sourceFilename = path.relative(
|
||||
path.dirname(commander.outFile),
|
||||
sourceFilename,
|
||||
);
|
||||
}
|
||||
sourceFilename = slash(sourceFilename);
|
||||
|
||||
util.compile(
|
||||
filename,
|
||||
defaults(
|
||||
{
|
||||
sourceFileName: sourceFilename,
|
||||
},
|
||||
opts,
|
||||
),
|
||||
function(err, res) {
|
||||
if (err) throw err;
|
||||
|
||||
filesProcessed++;
|
||||
if (res) results[index] = res;
|
||||
|
||||
if (filesProcessed === _filenames.length) {
|
||||
output();
|
||||
try {
|
||||
return await util.compile(
|
||||
filename,
|
||||
defaults(
|
||||
{
|
||||
sourceFileName: sourceFilename,
|
||||
// Since we're compiling everything to be merged together,
|
||||
// "inline" applies to the final output file, but to the individual
|
||||
// files being concatenated.
|
||||
sourceMaps:
|
||||
babelOptions.sourceMaps === "inline"
|
||||
? true
|
||||
: babelOptions.sourceMaps,
|
||||
},
|
||||
babelOptions,
|
||||
),
|
||||
);
|
||||
} catch (err) {
|
||||
if (!cliOptions.watch) {
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const files = function() {
|
||||
if (!commander.skipInitialBuild) {
|
||||
walk();
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
output(results);
|
||||
}
|
||||
|
||||
async function files(filenames) {
|
||||
if (!cliOptions.skipInitialBuild) {
|
||||
await walk(filenames);
|
||||
}
|
||||
|
||||
if (commander.watch) {
|
||||
if (cliOptions.watch) {
|
||||
const chokidar = util.requireChokidar();
|
||||
chokidar
|
||||
.watch(filenames, {
|
||||
@@ -196,25 +205,26 @@ export default function(commander, filenames, opts) {
|
||||
},
|
||||
})
|
||||
.on("all", function(type, filename) {
|
||||
if (!util.isCompilableExtension(filename, commander.extensions)) {
|
||||
if (!util.isCompilableExtension(filename, cliOptions.extensions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === "add" || type === "change") {
|
||||
util.log(type + " " + filename);
|
||||
try {
|
||||
walk();
|
||||
} catch (err) {
|
||||
console.error(err.stack);
|
||||
if (cliOptions.verbose) {
|
||||
console.log(type + " " + filename);
|
||||
}
|
||||
|
||||
walk(filenames).catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (filenames.length) {
|
||||
files();
|
||||
if (cliOptions.filenames.length) {
|
||||
await files(cliOptions.filenames);
|
||||
} else {
|
||||
stdin();
|
||||
await stdin();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,264 +1,13 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import fs from "fs";
|
||||
import commander from "commander";
|
||||
import { version } from "@babel/core";
|
||||
import uniq from "lodash/uniq";
|
||||
import glob from "glob";
|
||||
|
||||
import parseArgv from "./options";
|
||||
import dirCommand from "./dir";
|
||||
import fileCommand from "./file";
|
||||
|
||||
import pkg from "../../package.json";
|
||||
const opts = parseArgv(process.argv);
|
||||
|
||||
function booleanify(val: any): boolean | any {
|
||||
if (val === "true" || val == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val === "false" || val == 0 || !val) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
function collect(value, previousValue): Array<string> {
|
||||
// If the user passed the option with no value, like "babel file.js --presets", do nothing.
|
||||
if (typeof value !== "string") return previousValue;
|
||||
|
||||
const values = value.split(",");
|
||||
|
||||
return previousValue ? previousValue.concat(values) : values;
|
||||
}
|
||||
|
||||
// Standard Babel input configs.
|
||||
commander.option(
|
||||
"-f, --filename [filename]",
|
||||
"filename to use when reading from stdin - this will be used in source-maps, errors etc",
|
||||
);
|
||||
commander.option(
|
||||
"--presets [list]",
|
||||
"comma-separated list of preset names",
|
||||
collect,
|
||||
);
|
||||
commander.option(
|
||||
"--plugins [list]",
|
||||
"comma-separated list of plugin names",
|
||||
collect,
|
||||
);
|
||||
commander.option("--config-file [path]", "Path a to .babelrc file to use");
|
||||
commander.option(
|
||||
"--env-name [name]",
|
||||
"The name of the 'env' to use when loading configs and plugins. " +
|
||||
"Defaults to the value of BABEL_ENV, or else NODE_ENV, or else 'development'.",
|
||||
);
|
||||
|
||||
// Basic file input configuration.
|
||||
commander.option("--source-type [script|module]", "");
|
||||
commander.option(
|
||||
"--no-babelrc",
|
||||
"Whether or not to look up .babelrc and .babelignore files",
|
||||
);
|
||||
commander.option(
|
||||
"--ignore [list]",
|
||||
"list of glob paths to **not** compile",
|
||||
collect,
|
||||
);
|
||||
commander.option(
|
||||
"--only [list]",
|
||||
"list of glob paths to **only** compile",
|
||||
collect,
|
||||
);
|
||||
|
||||
// Misc babel config.
|
||||
commander.option(
|
||||
"--no-highlight-code",
|
||||
"enable/disable ANSI syntax highlighting of code frames (on by default)",
|
||||
);
|
||||
|
||||
// General output formatting.
|
||||
commander.option(
|
||||
"--no-comments",
|
||||
"write comments to generated output (true by default)",
|
||||
);
|
||||
commander.option(
|
||||
"--retain-lines",
|
||||
"retain line numbers - will result in really ugly code",
|
||||
);
|
||||
commander.option(
|
||||
"--compact [true|false|auto]",
|
||||
"do not include superfluous whitespace characters and line terminators",
|
||||
booleanify,
|
||||
);
|
||||
commander.option("--minified", "save as much bytes when printing [true|false]");
|
||||
commander.option(
|
||||
"--auxiliary-comment-before [string]",
|
||||
"print a comment before any injected non-user code",
|
||||
);
|
||||
commander.option(
|
||||
"--auxiliary-comment-after [string]",
|
||||
"print a comment after any injected non-user code",
|
||||
);
|
||||
|
||||
// General soucemap formatting.
|
||||
commander.option("-s, --source-maps [true|false|inline|both]", "", booleanify);
|
||||
commander.option(
|
||||
"--source-map-target [string]",
|
||||
"set `file` on returned source map",
|
||||
);
|
||||
commander.option(
|
||||
"--source-file-name [string]",
|
||||
"set `sources[0]` on returned source map",
|
||||
);
|
||||
commander.option(
|
||||
"--source-root [filename]",
|
||||
"the root from which all sources are relative",
|
||||
);
|
||||
|
||||
// Config params for certain module output formats.
|
||||
commander.option(
|
||||
"--module-root [filename]",
|
||||
"optional prefix for the AMD module formatter that will be prepend to the filename on module definitions",
|
||||
);
|
||||
commander.option("-M, --module-ids", "insert an explicit id for modules");
|
||||
commander.option(
|
||||
"--module-id [string]",
|
||||
"specify a custom name for module ids",
|
||||
);
|
||||
|
||||
// "babel" command specific arguments that are not passed to @babel/core.
|
||||
commander.option(
|
||||
"-x, --extensions [extensions]",
|
||||
"List of extensions to compile when a directory has been input [.es6,.js,.es,.jsx,.mjs]",
|
||||
collect,
|
||||
);
|
||||
commander.option(
|
||||
"--keep-file-extension",
|
||||
"Preserve the file extensions of the input files",
|
||||
);
|
||||
commander.option("-w, --watch", "Recompile files on changes");
|
||||
commander.option(
|
||||
"--skip-initial-build",
|
||||
"Do not compile files before watching",
|
||||
);
|
||||
commander.option(
|
||||
"-o, --out-file [out]",
|
||||
"Compile all input files into a single file",
|
||||
);
|
||||
commander.option(
|
||||
"-d, --out-dir [out]",
|
||||
"Compile an input directory of modules into an output directory",
|
||||
);
|
||||
commander.option(
|
||||
"--relative",
|
||||
"Compile into an output directory relative to input directory or file. Requires --out-dir [out]",
|
||||
);
|
||||
commander.option(
|
||||
"-D, --copy-files",
|
||||
"When compiling a directory copy over non-compilable files",
|
||||
);
|
||||
commander.option(
|
||||
"--include-dotfiles",
|
||||
"Include dotfiles when compiling and copying non-compilable files",
|
||||
);
|
||||
commander.option("--verbose", "Log everything");
|
||||
commander.option(
|
||||
"--delete-dir-on-start",
|
||||
"Delete the out directory before compilation",
|
||||
);
|
||||
|
||||
commander.version(pkg.version + " (@babel/core " + version + ")");
|
||||
commander.usage("[options] <files ...>");
|
||||
commander.parse(process.argv);
|
||||
|
||||
//
|
||||
|
||||
const errors = [];
|
||||
|
||||
let filenames = commander.args.reduce(function(globbed, input) {
|
||||
let files = glob.sync(input);
|
||||
if (!files.length) files = [input];
|
||||
return globbed.concat(files);
|
||||
}, []);
|
||||
|
||||
filenames = uniq(filenames);
|
||||
|
||||
filenames.forEach(function(filename) {
|
||||
if (!fs.existsSync(filename)) {
|
||||
errors.push(filename + " doesn't exist");
|
||||
}
|
||||
const fn = opts.cliOptions.outDir ? dirCommand : fileCommand;
|
||||
fn(opts).catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
if (commander.outDir && !filenames.length) {
|
||||
errors.push("filenames required for --out-dir");
|
||||
}
|
||||
|
||||
if (commander.outFile && commander.outDir) {
|
||||
errors.push("cannot have --out-file and --out-dir");
|
||||
}
|
||||
|
||||
if (commander.relative && !commander.outDir) {
|
||||
errors.push("output directory required for --relative");
|
||||
}
|
||||
|
||||
if (commander.watch) {
|
||||
if (!commander.outFile && !commander.outDir) {
|
||||
errors.push("--watch requires --out-file or --out-dir");
|
||||
}
|
||||
|
||||
if (!filenames.length) {
|
||||
errors.push("--watch requires filenames");
|
||||
}
|
||||
}
|
||||
|
||||
if (commander.skipInitialBuild && !commander.watch) {
|
||||
errors.push("--skip-initial-build requires --watch");
|
||||
}
|
||||
if (commander.deleteDirOnStart && !commander.outDir) {
|
||||
errors.push("--delete-dir-on-start requires --out-dir");
|
||||
}
|
||||
|
||||
if (
|
||||
!commander.outDir &&
|
||||
filenames.length === 0 &&
|
||||
typeof commander.filename !== "string" &&
|
||||
commander.babelrc !== false
|
||||
) {
|
||||
errors.push(
|
||||
"stdin compilation requires either -f/--filename [filename] or --no-babelrc",
|
||||
);
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
console.error(errors.join(". "));
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const opts = commander.opts();
|
||||
|
||||
// Delete options that are specific to @babel/cli and shouldn't be passed to @babel/core.
|
||||
delete opts.version;
|
||||
delete opts.extensions;
|
||||
delete opts.watch;
|
||||
delete opts.skipInitialBuild;
|
||||
delete opts.outFile;
|
||||
delete opts.outDir;
|
||||
delete opts.copyFiles;
|
||||
delete opts.includeDotfiles;
|
||||
delete opts.verbose;
|
||||
delete opts.deleteDirOnStart;
|
||||
delete opts.keepFileExtension;
|
||||
delete opts.relative;
|
||||
delete opts.sourceMapTarget;
|
||||
|
||||
// Commander will default the "--no-" arguments to true, but we want to leave them undefined so that
|
||||
// @babel/core can handle the default-assignment logic on its own.
|
||||
if (opts.babelrc === true) opts.babelrc = undefined;
|
||||
if (opts.comments === true) opts.comments = undefined;
|
||||
if (opts.highlightCode === true) opts.highlightCode = undefined;
|
||||
|
||||
const fn = commander.outDir ? dirCommand : fileCommand;
|
||||
fn(commander, filenames, opts);
|
||||
|
||||
283
packages/babel-cli/src/babel/options.js
Normal file
283
packages/babel-cli/src/babel/options.js
Normal file
@@ -0,0 +1,283 @@
|
||||
import fs from "fs";
|
||||
|
||||
import commander from "commander";
|
||||
import { version } from "@babel/core";
|
||||
import uniq from "lodash/uniq";
|
||||
import glob from "glob";
|
||||
|
||||
import pkg from "../../package.json";
|
||||
|
||||
// Standard Babel input configs.
|
||||
commander.option(
|
||||
"-f, --filename [filename]",
|
||||
"filename to use when reading from stdin - this will be used in source-maps, errors etc",
|
||||
);
|
||||
commander.option(
|
||||
"--presets [list]",
|
||||
"comma-separated list of preset names",
|
||||
collect,
|
||||
);
|
||||
commander.option(
|
||||
"--plugins [list]",
|
||||
"comma-separated list of plugin names",
|
||||
collect,
|
||||
);
|
||||
commander.option("--config-file [path]", "Path a to .babelrc file to use");
|
||||
commander.option(
|
||||
"--env-name [name]",
|
||||
"The name of the 'env' to use when loading configs and plugins. " +
|
||||
"Defaults to the value of BABEL_ENV, or else NODE_ENV, or else 'development'.",
|
||||
);
|
||||
|
||||
// Basic file input configuration.
|
||||
commander.option("--source-type [script|module]", "");
|
||||
commander.option(
|
||||
"--no-babelrc",
|
||||
"Whether or not to look up .babelrc and .babelignore files",
|
||||
);
|
||||
commander.option(
|
||||
"--ignore [list]",
|
||||
"list of glob paths to **not** compile",
|
||||
collect,
|
||||
);
|
||||
commander.option(
|
||||
"--only [list]",
|
||||
"list of glob paths to **only** compile",
|
||||
collect,
|
||||
);
|
||||
|
||||
// Misc babel config.
|
||||
commander.option(
|
||||
"--no-highlight-code",
|
||||
"enable/disable ANSI syntax highlighting of code frames (on by default)",
|
||||
);
|
||||
|
||||
// General output formatting.
|
||||
commander.option(
|
||||
"--no-comments",
|
||||
"write comments to generated output (true by default)",
|
||||
);
|
||||
commander.option(
|
||||
"--retain-lines",
|
||||
"retain line numbers - will result in really ugly code",
|
||||
);
|
||||
commander.option(
|
||||
"--compact [true|false|auto]",
|
||||
"do not include superfluous whitespace characters and line terminators",
|
||||
booleanify,
|
||||
);
|
||||
commander.option("--minified", "save as much bytes when printing [true|false]");
|
||||
commander.option(
|
||||
"--auxiliary-comment-before [string]",
|
||||
"print a comment before any injected non-user code",
|
||||
);
|
||||
commander.option(
|
||||
"--auxiliary-comment-after [string]",
|
||||
"print a comment after any injected non-user code",
|
||||
);
|
||||
|
||||
// General soucemap formatting.
|
||||
commander.option("-s, --source-maps [true|false|inline|both]", "", booleanify);
|
||||
commander.option(
|
||||
"--source-map-target [string]",
|
||||
"set `file` on returned source map",
|
||||
);
|
||||
commander.option(
|
||||
"--source-file-name [string]",
|
||||
"set `sources[0]` on returned source map",
|
||||
);
|
||||
commander.option(
|
||||
"--source-root [filename]",
|
||||
"the root from which all sources are relative",
|
||||
);
|
||||
|
||||
// Config params for certain module output formats.
|
||||
commander.option(
|
||||
"--module-root [filename]",
|
||||
"optional prefix for the AMD module formatter that will be prepend to the filename on module definitions",
|
||||
);
|
||||
commander.option("-M, --module-ids", "insert an explicit id for modules");
|
||||
commander.option(
|
||||
"--module-id [string]",
|
||||
"specify a custom name for module ids",
|
||||
);
|
||||
|
||||
// "babel" command specific arguments that are not passed to @babel/core.
|
||||
commander.option(
|
||||
"-x, --extensions [extensions]",
|
||||
"List of extensions to compile when a directory has been input [.es6,.js,.es,.jsx,.mjs]",
|
||||
collect,
|
||||
);
|
||||
commander.option(
|
||||
"--keep-file-extension",
|
||||
"Preserve the file extensions of the input files",
|
||||
);
|
||||
commander.option("-w, --watch", "Recompile files on changes");
|
||||
commander.option(
|
||||
"--skip-initial-build",
|
||||
"Do not compile files before watching",
|
||||
);
|
||||
commander.option(
|
||||
"-o, --out-file [out]",
|
||||
"Compile all input files into a single file",
|
||||
);
|
||||
commander.option(
|
||||
"-d, --out-dir [out]",
|
||||
"Compile an input directory of modules into an output directory",
|
||||
);
|
||||
commander.option(
|
||||
"--relative",
|
||||
"Compile into an output directory relative to input directory or file. Requires --out-dir [out]",
|
||||
);
|
||||
commander.option(
|
||||
"-D, --copy-files",
|
||||
"When compiling a directory copy over non-compilable files",
|
||||
);
|
||||
commander.option(
|
||||
"--include-dotfiles",
|
||||
"Include dotfiles when compiling and copying non-compilable files",
|
||||
);
|
||||
commander.option("--verbose", "Log everything");
|
||||
commander.option(
|
||||
"--delete-dir-on-start",
|
||||
"Delete the out directory before compilation",
|
||||
);
|
||||
|
||||
commander.version(pkg.version + " (@babel/core " + version + ")");
|
||||
commander.usage("[options] <files ...>");
|
||||
|
||||
export default function parseArgv(args: Array<string>) {
|
||||
//
|
||||
commander.parse(args);
|
||||
|
||||
const errors = [];
|
||||
|
||||
let filenames = commander.args.reduce(function(globbed, input) {
|
||||
let files = glob.sync(input);
|
||||
if (!files.length) files = [input];
|
||||
return globbed.concat(files);
|
||||
}, []);
|
||||
|
||||
filenames = uniq(filenames);
|
||||
|
||||
filenames.forEach(function(filename) {
|
||||
if (!fs.existsSync(filename)) {
|
||||
errors.push(filename + " doesn't exist");
|
||||
}
|
||||
});
|
||||
|
||||
if (commander.outDir && !filenames.length) {
|
||||
errors.push("filenames required for --out-dir");
|
||||
}
|
||||
|
||||
if (commander.outFile && commander.outDir) {
|
||||
errors.push("cannot have --out-file and --out-dir");
|
||||
}
|
||||
|
||||
if (commander.relative && !commander.outDir) {
|
||||
errors.push("output directory required for --relative");
|
||||
}
|
||||
|
||||
if (commander.watch) {
|
||||
if (!commander.outFile && !commander.outDir) {
|
||||
errors.push("--watch requires --out-file or --out-dir");
|
||||
}
|
||||
|
||||
if (!filenames.length) {
|
||||
errors.push("--watch requires filenames");
|
||||
}
|
||||
}
|
||||
|
||||
if (commander.skipInitialBuild && !commander.watch) {
|
||||
errors.push("--skip-initial-build requires --watch");
|
||||
}
|
||||
if (commander.deleteDirOnStart && !commander.outDir) {
|
||||
errors.push("--delete-dir-on-start requires --out-dir");
|
||||
}
|
||||
|
||||
if (
|
||||
!commander.outDir &&
|
||||
filenames.length === 0 &&
|
||||
typeof commander.filename !== "string" &&
|
||||
commander.babelrc !== false
|
||||
) {
|
||||
errors.push(
|
||||
"stdin compilation requires either -f/--filename [filename] or --no-babelrc",
|
||||
);
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
console.error(errors.join(". "));
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const opts = commander.opts();
|
||||
|
||||
return {
|
||||
babelOptions: {
|
||||
presets: opts.presets,
|
||||
plugins: opts.plugins,
|
||||
configFile: opts.configFile,
|
||||
envName: opts.envName,
|
||||
sourceType: opts.sourceType,
|
||||
ignore: opts.ignore,
|
||||
only: opts.only,
|
||||
retainLines: opts.retainLines,
|
||||
compact: opts.compact,
|
||||
minified: opts.minified,
|
||||
auxiliaryCommentBefore: opts.auxiliaryCommentBefore,
|
||||
auxiliaryCommentAfter: opts.auxiliaryCommentAfter,
|
||||
sourceMaps: opts.sourceMaps,
|
||||
sourceFileName: opts.sourceFileName,
|
||||
sourceRoot: opts.sourceRoot,
|
||||
moduleRoot: opts.moduleRoot,
|
||||
moduleIds: opts.moduleIds,
|
||||
moduleId: opts.moduleId,
|
||||
|
||||
// Commander will default the "--no-" arguments to true, but we want to
|
||||
// leave them undefined so that @babel/core can handle the
|
||||
// default-assignment logic on its own.
|
||||
babelrc: opts.babelrc === true ? undefined : opts.babelrc,
|
||||
highlightCode:
|
||||
opts.highlightCode === true ? undefined : opts.highlightCode,
|
||||
comments: opts.comments === true ? undefined : opts.comments,
|
||||
},
|
||||
cliOptions: {
|
||||
filename: opts.filename,
|
||||
filenames,
|
||||
extensions: opts.extensions,
|
||||
keepFileExtension: opts.keepFileExtension,
|
||||
watch: opts.watch,
|
||||
skipInitialBuild: opts.skipInitialBuild,
|
||||
outFile: opts.outFile,
|
||||
outDir: opts.outDir,
|
||||
relative: opts.relative,
|
||||
copyFiles: opts.copyFiles,
|
||||
includeDotfiles: opts.includeDotfiles,
|
||||
verbose: opts.verbose,
|
||||
deleteDirOnStart: opts.deleteDirOnStart,
|
||||
sourceMapTarget: opts.sourceMapTarget,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function booleanify(val: any): boolean | any {
|
||||
if (val === "true" || val == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val === "false" || val == 0 || !val) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
function collect(value, previousValue): Array<string> {
|
||||
// If the user passed the option with no value, like "babel file.js --presets", do nothing.
|
||||
if (typeof value !== "string") return previousValue;
|
||||
|
||||
const values = value.split(",");
|
||||
|
||||
return previousValue ? previousValue.concat(values) : values;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import commander from "commander";
|
||||
import readdirRecursive from "fs-readdir-recursive";
|
||||
import * as babel from "@babel/core";
|
||||
import includes from "lodash/includes";
|
||||
@@ -46,29 +45,26 @@ export function addSourceMappingUrl(code, loc) {
|
||||
return code + "\n//# sourceMappingURL=" + path.basename(loc);
|
||||
}
|
||||
|
||||
export function log(msg, force) {
|
||||
if (force === true || commander.verbose) console.log(msg);
|
||||
}
|
||||
|
||||
export function transform(filename, code, opts, callback) {
|
||||
opts = Object.assign({}, opts, {
|
||||
export function transform(filename, code, opts) {
|
||||
opts = {
|
||||
...opts,
|
||||
filename,
|
||||
});
|
||||
};
|
||||
|
||||
babel.transform(code, opts, callback);
|
||||
return new Promise((resolve, reject) => {
|
||||
babel.transform(code, opts, (err, result) => {
|
||||
if (err) reject(err);
|
||||
else resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function compile(filename, opts, callback) {
|
||||
babel.transformFile(filename, opts, function(err, res) {
|
||||
if (err) {
|
||||
if (commander.watch) {
|
||||
console.error(err);
|
||||
return callback(null, null);
|
||||
} else {
|
||||
return callback(err);
|
||||
}
|
||||
}
|
||||
return callback(null, res);
|
||||
export function compile(filename, opts) {
|
||||
return new Promise((resolve, reject) => {
|
||||
babel.transformFile(filename, opts, (err, result) => {
|
||||
if (err) reject(err);
|
||||
else resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
🎉 Successfully compiled 0 files with Babel.
|
||||
|
||||
@@ -4,4 +4,4 @@ var foo = function foo() {
|
||||
return 4;
|
||||
};
|
||||
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm9yaWdpbmFsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsVUFBVSxlO1MsQUFBTTtBQUFDIiwiZmlsZSI6InNjcmlwdDIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZm9vID0gKCkgPT4gNDsiXX0=
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm9yaWdpbmFsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsSUFBQSxNQUFVLFNBQVYsR0FBVSxHO1NBQU0sQztBQUFDLENBQWpCIiwiZmlsZSI6InNjcmlwdDIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZm9vID0gKCkgPT4gNDsiXX0=
|
||||
|
||||
@@ -1 +1 @@
|
||||
SyntaxError: test.js: Unexpected token, expected ";" (2:10)
|
||||
SyntaxError: <CWD>/test.js: Unexpected token, expected ";" (2:10)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
const includes = require("lodash/includes");
|
||||
const readdir = require("fs-readdir-recursive");
|
||||
const helper = require("@babel/helper-fixtures");
|
||||
const rimraf = require("rimraf");
|
||||
@@ -37,7 +36,9 @@ const readDir = function(loc, filter) {
|
||||
|
||||
const saveInFiles = function(files) {
|
||||
// Place an empty .babelrc in each test so tests won't unexpectedly get to repo-level config.
|
||||
outputFileSync(".babelrc", "{}");
|
||||
if (!fs.existsSync(".babelrc")) {
|
||||
outputFileSync(".babelrc", "{}");
|
||||
}
|
||||
|
||||
Object.keys(files).forEach(function(filename) {
|
||||
const content = files[filename];
|
||||
@@ -45,13 +46,26 @@ const saveInFiles = function(files) {
|
||||
});
|
||||
};
|
||||
|
||||
const assertTest = function(stdout, stderr, opts) {
|
||||
const replacePaths = function(str, cwd) {
|
||||
let prev;
|
||||
do {
|
||||
prev = str;
|
||||
str = str.replace(cwd, "<CWD>");
|
||||
} while (str !== prev);
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
const assertTest = function(stdout, stderr, opts, cwd) {
|
||||
stdout = replacePaths(stdout, cwd);
|
||||
stderr = replacePaths(stderr, cwd);
|
||||
|
||||
const expectStderr = opts.stderr.trim();
|
||||
stderr = stderr.trim();
|
||||
|
||||
if (opts.stderr) {
|
||||
if (opts.stderrContains) {
|
||||
expect(includes(stderr, expectStderr)).toBe(true);
|
||||
expect(stderr).toContain(expectStderr);
|
||||
} else {
|
||||
expect(stderr).toBe(expectStderr);
|
||||
}
|
||||
@@ -65,7 +79,7 @@ const assertTest = function(stdout, stderr, opts) {
|
||||
|
||||
if (opts.stdout) {
|
||||
if (opts.stdoutContains) {
|
||||
expect(includes(stdout, expectStdout)).toBe(true);
|
||||
expect(stdout).toContain(expectStdout);
|
||||
} else {
|
||||
expect(stdout).toBe(expectStdout);
|
||||
}
|
||||
@@ -137,7 +151,7 @@ const buildTest = function(binName, testName, opts) {
|
||||
let err;
|
||||
|
||||
try {
|
||||
assertTest(stdout, stderr, opts);
|
||||
assertTest(stdout, stderr, opts, tmpLoc);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
|
||||
@@ -2,141 +2,18 @@
|
||||
|
||||
> Generate errors that contain a code frame that point to source locations.
|
||||
|
||||
See our website [@babel/code-frame](https://new.babeljs.io/docs/en/next/babel-code-frame.html) for more information.
|
||||
|
||||
## Install
|
||||
|
||||
Using npm:
|
||||
|
||||
```sh
|
||||
npm install --save-dev @babel/code-frame
|
||||
npm install --save @babel/code-frame
|
||||
```
|
||||
|
||||
## Usage
|
||||
or using yarn:
|
||||
|
||||
```js
|
||||
import { codeFrameColumns } from '@babel/code-frame';
|
||||
|
||||
const rawLines = `class Foo {
|
||||
constructor()
|
||||
}`;
|
||||
const location = { start: { line: 2, column: 16 } };
|
||||
|
||||
const result = codeFrameColumns(rawLines, location, { /* options */ });
|
||||
|
||||
console.log(result);
|
||||
```
|
||||
|
||||
```
|
||||
1 | class Foo {
|
||||
> 2 | constructor()
|
||||
| ^
|
||||
3 | }
|
||||
```
|
||||
|
||||
If the column number is not known, you may omit it.
|
||||
|
||||
You can also pass an `end` hash in `location`.
|
||||
|
||||
```js
|
||||
import { codeFrameColumns } from '@babel/code-frame';
|
||||
|
||||
const rawLines = `class Foo {
|
||||
constructor() {
|
||||
console.log("hello");
|
||||
}
|
||||
}`;
|
||||
const location = { start: { line: 2, column: 17 }, end: { line: 4, column: 3 } };
|
||||
|
||||
const result = codeFrameColumns(rawLines, location, { /* options */ });
|
||||
|
||||
console.log(result);
|
||||
```
|
||||
|
||||
```
|
||||
1 | class Foo {
|
||||
> 2 | constructor() {
|
||||
| ^
|
||||
> 3 | console.log("hello");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> 4 | }
|
||||
| ^^^
|
||||
5 | };
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### `highlightCode`
|
||||
|
||||
`boolean`, defaults to `false`.
|
||||
|
||||
Toggles syntax highlighting the code as JavaScript for terminals.
|
||||
|
||||
|
||||
### `linesAbove`
|
||||
|
||||
`number`, defaults to `2`.
|
||||
|
||||
Adjust the number of lines to show above the error.
|
||||
|
||||
### `linesBelow`
|
||||
|
||||
`number`, defaults to `3`.
|
||||
|
||||
Adjust the number of lines to show below the error.
|
||||
|
||||
### `forceColor`
|
||||
|
||||
`boolean`, defaults to `false`.
|
||||
|
||||
Enable this to forcibly syntax highlight the code as JavaScript (for non-terminals); overrides `highlightCode`.
|
||||
|
||||
### `message`
|
||||
|
||||
`string`, otherwise nothing
|
||||
|
||||
Pass in a string to be displayed inline (if possible) next to the highlighted
|
||||
location in the code. If it can't be positioned inline, it will be placed above
|
||||
the code frame.
|
||||
|
||||
```
|
||||
1 | class Foo {
|
||||
> 2 | constructor()
|
||||
| ^ Missing {
|
||||
3 | };
|
||||
```
|
||||
|
||||
## Upgrading from prior versions
|
||||
|
||||
Prior to version 7, the only API exposed by this module was for a single line and optional column pointer. The old API will now log a deprecation warning.
|
||||
|
||||
The new API takes a `location` object, similar to what is available in an AST.
|
||||
|
||||
This is an example of the deprecated (but still available) API:
|
||||
|
||||
```js
|
||||
import codeFrame from '@babel/code-frame';
|
||||
|
||||
const rawLines = `class Foo {
|
||||
constructor()
|
||||
}`;
|
||||
const lineNumber = 2;
|
||||
const colNumber = 16;
|
||||
|
||||
const result = codeFrame(rawLines, lineNumber, colNumber, { /* options */ });
|
||||
|
||||
console.log(result);
|
||||
```
|
||||
|
||||
To get the same highlighting using the new API:
|
||||
|
||||
```js
|
||||
import { codeFrameColumns } from '@babel/code-frame';
|
||||
|
||||
const rawLines = `class Foo {
|
||||
constructor() {
|
||||
console.log("hello");
|
||||
}
|
||||
}`;
|
||||
const location = { start: { line: 2, column: 16 } };
|
||||
|
||||
const result = codeFrameColumns(rawLines, location, { /* options */ });
|
||||
|
||||
console.log(result);
|
||||
```sh
|
||||
yarn add --save @babel/code-frame
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@babel/code-frame",
|
||||
"version": "7.0.0-beta.46",
|
||||
"version": "7.0.0-beta.50",
|
||||
"description": "Generate errors that contain a code frame that point to source locations.",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
@@ -8,7 +8,7 @@
|
||||
"repository": "https://github.com/babel/babel/tree/master/packages/babel-code-frame",
|
||||
"main": "lib/index.js",
|
||||
"dependencies": {
|
||||
"@babel/highlight": "7.0.0-beta.46"
|
||||
"@babel/highlight": "7.0.0-beta.50"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chalk": "^2.0.0",
|
||||
|
||||
@@ -38,12 +38,15 @@ function getMarkerLines(
|
||||
source: Array<string>,
|
||||
opts: Object,
|
||||
): { start: number, end: number, markerLines: Object } {
|
||||
const startLoc: Location = Object.assign(
|
||||
{},
|
||||
{ column: 0, line: -1 },
|
||||
loc.start,
|
||||
);
|
||||
const endLoc: Location = Object.assign({}, startLoc, loc.end);
|
||||
const startLoc: Location = {
|
||||
column: 0,
|
||||
line: -1,
|
||||
...loc.start,
|
||||
};
|
||||
const endLoc: Location = {
|
||||
...startLoc,
|
||||
...loc.end,
|
||||
};
|
||||
const { linesAbove = 2, linesBelow = 3 } = opts || {};
|
||||
const startLine = startLoc.line;
|
||||
const startColumn = startLoc.column;
|
||||
|
||||
@@ -2,249 +2,18 @@
|
||||
|
||||
> Babel compiler core.
|
||||
|
||||
See our website [@babel/core](https://new.babeljs.io/docs/en/next/babel-core.html) for more information or the [issues](https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A%20core%22+is%3Aopen) associated with this package.
|
||||
|
||||
```javascript
|
||||
var babel = require("@babel/core");
|
||||
import { transform } from "@babel/core";
|
||||
import * as babel from "@babel/core";
|
||||
## Install
|
||||
|
||||
Using npm:
|
||||
|
||||
```sh
|
||||
npm install --save @babel/core
|
||||
```
|
||||
|
||||
All transformations will use your local configuration files (`.babelrc` or in `package.json`). See [options](#options) to disable it.
|
||||
or using yarn:
|
||||
|
||||
|
||||
## babel.transform(code: string, [options?](#options): Object, callback: Function)
|
||||
|
||||
Transforms the passed in `code`. Calling a callback with an object with the generated code,
|
||||
source map, and AST.
|
||||
|
||||
```js
|
||||
babel.transform(code, options, function(err, result) {
|
||||
result; // => { code, map, ast }
|
||||
});
|
||||
```sh
|
||||
yarn add --save @babel/core
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
babel.transform("code();", options, function(err, result) {
|
||||
result.code;
|
||||
result.map;
|
||||
result.ast;
|
||||
});
|
||||
```
|
||||
|
||||
### Compat Note:
|
||||
|
||||
In Babel 6, this method was synchronous and `transformSync` did not exist. For backward-compatibility,
|
||||
this function will behave synchronously if no callback is given. If you're starting with Babel 7
|
||||
and need synchronous behavior, please use `transformSync` since this backward-compat may be dropped in
|
||||
future major versions of Babel.
|
||||
|
||||
|
||||
## babel.transformSync(code: string, [options?](#options): Object)
|
||||
|
||||
Transforms the passed in `code`. Returning an object with the generated code,
|
||||
source map, and AST.
|
||||
|
||||
```js
|
||||
babel.transformSync(code, options) // => { code, map, ast }
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
var result = babel.transformSync("code();", options);
|
||||
result.code;
|
||||
result.map;
|
||||
result.ast;
|
||||
```
|
||||
|
||||
|
||||
## babel.transformFile(filename: string, [options?](#options): Object, callback: Function)
|
||||
|
||||
Asynchronously transforms the entire contents of a file.
|
||||
|
||||
```js
|
||||
babel.transformFile(filename, options, callback)
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
babel.transformFile("filename.js", options, function (err, result) {
|
||||
result; // => { code, map, ast }
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## babel.transformFileSync(filename: string, [options?](#options): Object)
|
||||
|
||||
Synchronous version of `babel.transformFile`. Returns the transformed contents of
|
||||
the `filename`.
|
||||
|
||||
```js
|
||||
babel.transformFileSync(filename, options) // => { code, map, ast }
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
babel.transformFileSync("filename.js", options).code;
|
||||
```
|
||||
|
||||
|
||||
## babel.transformFromAst(ast: Object, code?: string, [options?](#options): Object, callback: Function): FileNode | null
|
||||
|
||||
Given an [AST](https://astexplorer.net/), transform it.
|
||||
|
||||
```js
|
||||
const sourceCode = "if (true) return;";
|
||||
const parsedAst = babylon.parse(sourceCode, { allowReturnOutsideFunction: true });
|
||||
babel.transformFromAst(parsedAst, sourceCode, options, function(err, result) {
|
||||
const { code, map, ast } = result;
|
||||
});
|
||||
```
|
||||
|
||||
### Compat Note:
|
||||
|
||||
In Babel 6, this method was synchronous and `transformFromAstSync` did not exist. For backward-compatibility,
|
||||
this function will behave synchronously if no callback is given. If you're starting with Babel 7
|
||||
and need synchronous behavior, please use `transformFromAstSync` since this backward-compat may be dropped in
|
||||
future major versions of Babel.
|
||||
|
||||
|
||||
## babel.transformFromAstSync(ast: Object, code?: string, [options?](#options): Object)
|
||||
|
||||
Given an [AST](https://astexplorer.net/), transform it.
|
||||
|
||||
```js
|
||||
const sourceCode = "if (true) return;";
|
||||
const parsedAst = babylon.parse(sourceCode, { allowReturnOutsideFunction: true });
|
||||
const { code, map, ast } = babel.transformFromAstSync(parsedAst, sourceCode, options);
|
||||
```
|
||||
|
||||
## babel.parse(code: string, [options?](#options): Object)
|
||||
|
||||
Given some code, parse it using Babel's standard behavior. Referenced presets and
|
||||
plugins will be loaded such that optional syntax plugins are automatically
|
||||
enabled.
|
||||
|
||||
|
||||
## Advanced APIs
|
||||
|
||||
Many systems that wrap Babel like to automatically inject plugins and presets,
|
||||
or override options. To accomplish this goal, Babel exposes several functions
|
||||
that aid in loading the configuration part-way without transforming.
|
||||
|
||||
### babel.loadOptions([options?](#options): Object)
|
||||
|
||||
Resolve Babel's options fully, resulting in an options object where:
|
||||
|
||||
* `opts.plugins` is a full list of `Plugin` instances.
|
||||
* `opts.presets` is empty and all presets are flattened into `opts`.
|
||||
* It can be safely passed back to Babel. Fields like `babelrc` have been set to
|
||||
false so that later calls to Babel will not make a second attempt to load
|
||||
config files.
|
||||
|
||||
`Plugin` instances aren't meant to be manipulated directly, but often
|
||||
callers will serialize this `opts` to JSON to use it as a cache key representing
|
||||
the options Babel has received. Caching on this isn't 100% guaranteed to
|
||||
invalidate properly, but it is the best we have at the moment.
|
||||
|
||||
|
||||
### babel.loadPartialConfig([options?](#options): Object): PartialConfig
|
||||
|
||||
To allow systems to easily manipulate and validate a user's config, this function
|
||||
resolves the plugins and presets and proceeds no further. The expectation is
|
||||
that callers will take the config's `.options`, manipulate it as then see fit
|
||||
and pass it back to Babel again.
|
||||
|
||||
* `babelrc: string | void` - The path of the `.babelrc` file, if there was one.
|
||||
* `babelignore: string | void` - The path of the `.babelignore` file, if there was one.
|
||||
* `options: ValidatedOptions` - The partially resolved options, which can be manipulated and passed back to Babel again.
|
||||
* `plugins: Array<ConfigItem>` - See below.
|
||||
* `presets: Array<ConfigItem>` - See below.
|
||||
* It can be safely passed back to Babel. Fields like `babelrc` have been set
|
||||
to false so that later calls to Babel will not make a second attempt to
|
||||
load config files.
|
||||
* `hasFilesystemConfig(): boolean` - Check if the resolved config loaded any settings from the filesystem.
|
||||
|
||||
[`ConfigItem`](#configitem-type) instances expose properties to introspect the values, but each
|
||||
item should be treated as immutable. If changes are desired, the item should be
|
||||
removed from the list and replaced with either a normal Babel config value, or
|
||||
with a replacement item created by `babel.createConfigItem`. See that
|
||||
function for information about `ConfigItem` fields.
|
||||
|
||||
|
||||
### babel.createConfigItem(value: string | {} | Function | [string | {} | Function, {} | void], { dirname?: string, type?: "preset" | "plugin" }): ConfigItem
|
||||
|
||||
Allows build tooling to create and cache config items up front. If this function
|
||||
is called multiple times for a given plugin, Babel will call the plugin's function itself
|
||||
multiple times. If you have a clear set of expected plugins and presets to
|
||||
inject, pre-constructing the config items would be recommended.
|
||||
|
||||
|
||||
### `ConfigItem` type
|
||||
|
||||
Each `ConfigItem` exposes all of the information Babel knows. The fields are:
|
||||
|
||||
* `value: {} | Function` - The resolved value of the plugin.
|
||||
* `options: {} | void` - The options object passed to the plugin.
|
||||
* `dirname: string` - The path that the options are relative to.
|
||||
* `name: string | void` - The name that the user gave the plugin instance, e.g. `plugins: [ ['env', {}, 'my-env'] ]`
|
||||
* `file: Object | void` - Information about the plugin's file, if Babel knows it.
|
||||
* `request: string` - The file that the user requested, e.g. `"@babel/env"`
|
||||
* `resolved: string` - The full path of the resolved file, e.g. `"/tmp/node_modules/@babel/preset-env/lib/index.js"`
|
||||
|
||||
|
||||
## Options
|
||||
|
||||
<blockquote class="babel-callout babel-callout-info">
|
||||
<h4>Babel CLI</h4>
|
||||
<p>
|
||||
You can pass these options from the Babel CLI like so:
|
||||
</p>
|
||||
<p>
|
||||
<code>babel --name<span class="o">=</span>value</code>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
Following is a table of the options you can use:
|
||||
|
||||
| Option | Default | Description |
|
||||
| ------------------------ | -------------------- | ------------------------------- |
|
||||
| `ast` | `false` | Include the AST in the returned object |
|
||||
| `auxiliaryCommentAfter` | `null` | Attach a comment after all non-user injected code |
|
||||
| `auxiliaryCommentBefore` | `null` | Attach a comment before all non-user injected code |
|
||||
| `root` | `"."` | Specify the "root" folder that defines the location to search for "babel.config.js", and the default folder to allow `.babelrc` files inside of.|
|
||||
| `configFile` | `undefined` | The config file to load Babel's config from. Defaults to searching for "babel.config.js" inside the "root" folder. `false` will disable searching for config files.|
|
||||
| `babelrc` | `true` | Specify whether or not to use .babelrc and .babelignore files. Not available when using the CLI, [use `--no-babelrc` instead](https://babeljs.io/docs/usage/cli/#babel-ignoring-babelrc) |
|
||||
| `babelrcRoots` | `(root)` | Specify which packages should be search for .babelrc files when they are being compiled. `true` to _always_ search, or a path string or an array of paths to packages to search inside of. Defaults to only searching the "root" package. |
|
||||
| `envName` | env vars | Defaults to environment variable `BABEL_ENV` if set, or else `NODE_ENV` if set, or else it defaults to `"development"` |
|
||||
| `code` | `true` | Enable code generation |
|
||||
| `comments` | `true` | Output comments in generated output |
|
||||
| `compact` | `"auto"` | Do not include superfluous whitespace characters and line terminators. When set to `"auto"` compact is set to `true` on input sizes of >500KB |
|
||||
| `env` | `{}` | This is an object of keys that represent different environments. For example, you may have: `{ env: { production: { /* specific options */ } } }` which will use those options when the `envName` is `production` |
|
||||
| `extends` | `null` | A path to a `.babelrc` file to extend |
|
||||
| `filename` | `"unknown"` | Filename for use in errors etc |
|
||||
| `filenameRelative` | `(filename)` | Filename relative to `sourceRoot` |
|
||||
| `generatorOpts` | `{}` | An object containing the options to be passed down to the babel code generator, @babel/generator |
|
||||
| `getModuleId` | `null` | Specify a custom callback to generate a module id with. Called as `getModuleId(moduleName)`. If falsy value is returned then the generated module id is used |
|
||||
| `highlightCode` | `true` | ANSI highlight syntax error code frames |
|
||||
| `ignore` | `null` | Opposite to the `only` option. `ignore` is disregarded if `only` is specified |
|
||||
| `inputSourceMap` | `null` | A source map object that the output source map will be based on |
|
||||
| `minified` | `false` | Should the output be minified (not printing last semicolons in blocks, printing literal string values instead of escaped ones, stripping `()` from `new` when safe) |
|
||||
| `moduleId` | `null` | Specify a custom name for module ids |
|
||||
| `moduleIds` | `false` | If truthy, insert an explicit id for modules. By default, all modules are anonymous. (Not available for `common` modules) |
|
||||
| `moduleRoot` | `(sourceRoot)` | Optional prefix for the AMD module formatter that will be prepend to the filename on module definitions |
|
||||
| `only` | `null` | A [glob](https://github.com/isaacs/minimatch), regex, or mixed array of both, matching paths to **only** compile. Can also be an array of arrays containing paths to explicitly match. When attempting to compile a non-matching file it's returned verbatim |
|
||||
| `parserOpts` | `{}` | An object containing the options to be passed down to the babel parser, babylon |
|
||||
| `plugins` | `[]` | List of [plugins](https://babeljs.io/docs/plugins/) to load and use |
|
||||
| `presets` | `[]` | List of [presets](https://babeljs.io/docs/plugins/#presets) (a set of plugins) to load and use |
|
||||
| `retainLines` | `false` | Retain line numbers. This will lead to wacky code but is handy for scenarios where you can't use source maps. (**NOTE:** This will not retain the columns) |
|
||||
| `shouldPrintComment` | `null` | An optional callback that controls whether a comment should be output or not. Called as `shouldPrintComment(commentContents)`. **NOTE:** This overrides the `comment` option when used |
|
||||
| `sourceFileName` | `(filenameRelative)` | Set `sources[0]` on returned source map |
|
||||
| `sourceMaps` | `false` | If truthy, adds a `map` property to returned output. If set to `"inline"`, a comment with a sourceMappingURL directive is added to the bottom of the returned code. If set to `"both"` then a `map` property is returned as well as a source map comment appended. **This does not emit sourcemap files by itself!** To have sourcemaps emitted using the CLI, you must pass it the `--source-maps` option |
|
||||
| `sourceRoot` | `(moduleRoot)` | The root from which all sources are relative |
|
||||
| `sourceType` | `"module"` | Indicate the mode the code should be parsed in. Can be one of "script", "module", or "unambiguous". `"unambiguous"` will make Babel attempt to _guess_, based on the presence of ES6 `import` or `export` statements. Files with ES6 `import`s and `export`s are considered `"module"` and are otherwise `"script"`. |
|
||||
| `wrapPluginVisitorMethod`| `null` | An optional callback that can be used to wrap visitor methods. **NOTE:** This is useful for things like introspection, and not really needed for implementing anything. Called as `wrapPluginVisitorMethod(pluginAlias, visitorType, callback)`.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "@babel/core",
|
||||
"version": "7.0.0-beta.46",
|
||||
"version": "7.0.0-beta.50",
|
||||
"description": "Babel compiler core.",
|
||||
"main": "./lib/index.js",
|
||||
"main": "lib/index.js",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"license": "MIT",
|
||||
@@ -22,30 +22,32 @@
|
||||
"babel-core",
|
||||
"compiler"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"browser": {
|
||||
"./lib/config/files/index.js": "./lib/config/files/index-browser.js",
|
||||
"./lib/transform-file.js": "./lib/transform-file-browser.js",
|
||||
"./lib/transform-file-sync.js": "./lib/transform-file-sync-browser.js"
|
||||
"./lib/transform-file.js": "./lib/transform-file-browser.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "7.0.0-beta.46",
|
||||
"@babel/generator": "7.0.0-beta.46",
|
||||
"@babel/helpers": "7.0.0-beta.46",
|
||||
"@babel/template": "7.0.0-beta.46",
|
||||
"@babel/traverse": "7.0.0-beta.46",
|
||||
"@babel/types": "7.0.0-beta.46",
|
||||
"babylon": "7.0.0-beta.46",
|
||||
"@babel/code-frame": "7.0.0-beta.50",
|
||||
"@babel/generator": "7.0.0-beta.50",
|
||||
"@babel/helpers": "7.0.0-beta.50",
|
||||
"@babel/parser": "7.0.0-beta.50",
|
||||
"@babel/template": "7.0.0-beta.50",
|
||||
"@babel/traverse": "7.0.0-beta.50",
|
||||
"@babel/types": "7.0.0-beta.50",
|
||||
"convert-source-map": "^1.1.0",
|
||||
"debug": "^3.1.0",
|
||||
"json5": "^0.5.0",
|
||||
"lodash": "^4.2.0",
|
||||
"micromatch": "^2.3.11",
|
||||
"lodash": "^4.17.5",
|
||||
"micromatch": "^3.1.10",
|
||||
"resolve": "^1.3.2",
|
||||
"semver": "^5.4.1",
|
||||
"source-map": "^0.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/helper-transform-fixture-test-runner": "7.0.0-beta.46",
|
||||
"@babel/register": "7.0.0-beta.46"
|
||||
"@babel/helper-transform-fixture-test-runner": "7.0.0-beta.50",
|
||||
"@babel/register": "7.0.0-beta.50"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,9 @@ export type PresetInstance = {
|
||||
};
|
||||
|
||||
export type ConfigContext = {
|
||||
filename: string | null,
|
||||
filename: string | void,
|
||||
cwd: string,
|
||||
root: string,
|
||||
envName: string,
|
||||
};
|
||||
|
||||
@@ -130,27 +131,30 @@ export function buildRootChain(
|
||||
);
|
||||
if (!programmaticChain) return null;
|
||||
|
||||
const {
|
||||
root: rootDir = ".",
|
||||
babelrc = true,
|
||||
babelrcRoots,
|
||||
configFile: configFileName = true,
|
||||
} = opts;
|
||||
|
||||
const absoluteRoot = path.resolve(context.cwd, rootDir);
|
||||
|
||||
let configFile;
|
||||
if (typeof configFileName === "string") {
|
||||
configFile = loadConfig(configFileName, context.cwd, context.envName);
|
||||
} else if (configFileName === true) {
|
||||
configFile = findRootConfig(absoluteRoot, context.envName);
|
||||
if (typeof opts.configFile === "string") {
|
||||
configFile = loadConfig(opts.configFile, context.cwd, context.envName);
|
||||
} else if (opts.configFile !== false) {
|
||||
configFile = findRootConfig(context.root, context.envName);
|
||||
}
|
||||
|
||||
let { babelrc, babelrcRoots } = opts;
|
||||
|
||||
const configFileChain = emptyChain();
|
||||
if (configFile) {
|
||||
const result = loadFileChain(configFile, context);
|
||||
const validatedFile = validateConfigFile(configFile);
|
||||
const result = loadFileChain(validatedFile, context);
|
||||
if (!result) return null;
|
||||
|
||||
// Allow config files to toggle `.babelrc` resolution on and off and
|
||||
// specify where the roots are.
|
||||
if (babelrc === undefined) {
|
||||
babelrc = validatedFile.options.babelrc;
|
||||
}
|
||||
if (babelrcRoots === undefined) {
|
||||
babelrcRoots = validatedFile.options.babelrcRoots;
|
||||
}
|
||||
|
||||
mergeChain(configFileChain, result);
|
||||
}
|
||||
|
||||
@@ -163,9 +167,9 @@ export function buildRootChain(
|
||||
const fileChain = emptyChain();
|
||||
// resolve all .babelrc files
|
||||
if (
|
||||
babelrc &&
|
||||
(babelrc === true || babelrc === undefined) &&
|
||||
pkgData &&
|
||||
babelrcLoadEnabled(context, pkgData, babelrcRoots, absoluteRoot)
|
||||
babelrcLoadEnabled(context, pkgData, babelrcRoots)
|
||||
) {
|
||||
({ ignore: ignoreFile, config: babelrcFile } = findRelativeConfig(
|
||||
pkgData,
|
||||
@@ -180,7 +184,7 @@ export function buildRootChain(
|
||||
}
|
||||
|
||||
if (babelrcFile) {
|
||||
const result = loadFileChain(babelrcFile, context);
|
||||
const result = loadFileChain(validateBabelrcFile(babelrcFile), context);
|
||||
if (!result) return null;
|
||||
|
||||
mergeChain(fileChain, result);
|
||||
@@ -208,10 +212,11 @@ function babelrcLoadEnabled(
|
||||
context: ConfigContext,
|
||||
pkgData: FilePackageData,
|
||||
babelrcRoots: BabelrcSearch | void,
|
||||
absoluteRoot: string,
|
||||
): boolean {
|
||||
if (typeof babelrcRoots === "boolean") return babelrcRoots;
|
||||
|
||||
const absoluteRoot = context.root;
|
||||
|
||||
// Fast path to avoid having to load micromatch if the babelrc is just
|
||||
// loading in the standard root directory.
|
||||
if (babelrcRoots === undefined) {
|
||||
@@ -231,11 +236,34 @@ function babelrcLoadEnabled(
|
||||
return micromatch(pkgData.directories, babelrcPatterns).length > 0;
|
||||
}
|
||||
|
||||
const validateConfigFile = makeWeakCache(
|
||||
(file: ConfigFile): ValidatedFile => ({
|
||||
filepath: file.filepath,
|
||||
dirname: file.dirname,
|
||||
options: validate("configfile", file.options),
|
||||
}),
|
||||
);
|
||||
|
||||
const validateBabelrcFile = makeWeakCache(
|
||||
(file: ConfigFile): ValidatedFile => ({
|
||||
filepath: file.filepath,
|
||||
dirname: file.dirname,
|
||||
options: validate("babelrcfile", file.options),
|
||||
}),
|
||||
);
|
||||
|
||||
const validateExtendFile = makeWeakCache(
|
||||
(file: ConfigFile): ValidatedFile => ({
|
||||
filepath: file.filepath,
|
||||
dirname: file.dirname,
|
||||
options: validate("extendsfile", file.options),
|
||||
}),
|
||||
);
|
||||
|
||||
/**
|
||||
* Build a config chain for just the programmatic options passed into Babel.
|
||||
*/
|
||||
const loadProgrammaticChain = makeChainWalker({
|
||||
init: arg => arg,
|
||||
root: input => buildRootDescriptors(input, "base", createCachedDescriptors),
|
||||
env: (input, envName) =>
|
||||
buildEnvDescriptors(input, "base", createCachedDescriptors, envName),
|
||||
@@ -255,18 +283,12 @@ const loadProgrammaticChain = makeChainWalker({
|
||||
* Build a config chain for a given file.
|
||||
*/
|
||||
const loadFileChain = makeChainWalker({
|
||||
init: input => validateFile(input),
|
||||
root: file => loadFileDescriptors(file),
|
||||
env: (file, envName) => loadFileEnvDescriptors(file)(envName),
|
||||
overrides: (file, index) => loadFileOverridesDescriptors(file)(index),
|
||||
overridesEnv: (file, index, envName) =>
|
||||
loadFileOverridesEnvDescriptors(file)(index)(envName),
|
||||
});
|
||||
const validateFile = makeWeakCache((file: ConfigFile): ValidatedFile => ({
|
||||
filepath: file.filepath,
|
||||
dirname: file.dirname,
|
||||
options: validate("file", file.options),
|
||||
}));
|
||||
const loadFileDescriptors = makeWeakCache((file: ValidatedFile) =>
|
||||
buildRootDescriptors(file, file.filepath, createUncachedDescriptors),
|
||||
);
|
||||
@@ -350,25 +372,18 @@ function buildOverrideEnvDescriptors(
|
||||
: null;
|
||||
}
|
||||
|
||||
function makeChainWalker<
|
||||
ArgT,
|
||||
InnerT: { options: ValidatedOptions, dirname: string },
|
||||
>({
|
||||
init,
|
||||
function makeChainWalker<ArgT: { options: ValidatedOptions, dirname: string }>({
|
||||
root,
|
||||
env,
|
||||
overrides,
|
||||
overridesEnv,
|
||||
}: {
|
||||
init: ArgT => InnerT,
|
||||
root: InnerT => OptionsAndDescriptors,
|
||||
env: (InnerT, string) => OptionsAndDescriptors | null,
|
||||
overrides: (InnerT, number) => OptionsAndDescriptors,
|
||||
overridesEnv: (InnerT, number, string) => OptionsAndDescriptors | null,
|
||||
root: ArgT => OptionsAndDescriptors,
|
||||
env: (ArgT, string) => OptionsAndDescriptors | null,
|
||||
overrides: (ArgT, number) => OptionsAndDescriptors,
|
||||
overridesEnv: (ArgT, number, string) => OptionsAndDescriptors | null,
|
||||
}): (ArgT, ConfigContext, Set<ConfigFile> | void) => ConfigChain | null {
|
||||
return (arg, context, files = new Set()) => {
|
||||
const input = init(arg);
|
||||
|
||||
return (input, context, files = new Set()) => {
|
||||
const { dirname } = input;
|
||||
|
||||
const flattenedConfigs = [];
|
||||
@@ -442,7 +457,7 @@ function mergeExtendsChain(
|
||||
}
|
||||
|
||||
files.add(file);
|
||||
const fileChain = loadFileChain(file, context, files);
|
||||
const fileChain = loadFileChain(validateExtendFile(file), context, files);
|
||||
files.delete(file);
|
||||
|
||||
if (!fileChain) return false;
|
||||
@@ -480,7 +495,9 @@ function emptyChain(): ConfigChain {
|
||||
}
|
||||
|
||||
function normalizeOptions(opts: ValidatedOptions): ValidatedOptions {
|
||||
const options = Object.assign({}, opts);
|
||||
const options = {
|
||||
...opts,
|
||||
};
|
||||
delete options.extends;
|
||||
delete options.env;
|
||||
delete options.plugins;
|
||||
@@ -562,7 +579,7 @@ function configFieldIsApplicable(
|
||||
test: ConfigApplicableTest,
|
||||
dirname: string,
|
||||
): boolean {
|
||||
if (context.filename === null) {
|
||||
if (typeof context.filename !== "string") {
|
||||
throw new Error(
|
||||
`Configuration contains explicit test/include/exclude checks, but no filename was passed to Babel`,
|
||||
);
|
||||
@@ -588,7 +605,7 @@ function shouldIgnore(
|
||||
dirname: string,
|
||||
): boolean {
|
||||
if (ignore) {
|
||||
if (context.filename === null) {
|
||||
if (typeof context.filename !== "string") {
|
||||
throw new Error(
|
||||
`Configuration contains ignore checks, but no filename was passed to Babel`,
|
||||
);
|
||||
@@ -607,7 +624,7 @@ function shouldIgnore(
|
||||
}
|
||||
|
||||
if (only) {
|
||||
if (context.filename === null) {
|
||||
if (typeof context.filename !== "string") {
|
||||
throw new Error(
|
||||
`Configuration contains ignore checks, but no filename was passed to Babel`,
|
||||
);
|
||||
@@ -682,7 +699,7 @@ function matchesPatterns(
|
||||
|
||||
const getPossibleDirs = makeWeakCache((context: ConfigContextNamed) => {
|
||||
let current = context.filename;
|
||||
if (current === null) return [];
|
||||
if (typeof current !== "string") return [];
|
||||
|
||||
const possibleDirs = [current];
|
||||
while (true) {
|
||||
|
||||
@@ -277,7 +277,7 @@ function assertNoDuplicates(items: Array<UnloadedDescriptor>): void {
|
||||
[
|
||||
`Duplicate plugin/preset detected.`,
|
||||
`If you'd like to use two separate instances of a plugin,`,
|
||||
`they neen separate names, e.g.`,
|
||||
`they need separate names, e.g.`,
|
||||
``,
|
||||
` plugins: [`,
|
||||
` ['some-plugin', {}],`,
|
||||
|
||||
@@ -198,8 +198,9 @@ const readConfigJS = makeStrongCache(
|
||||
|
||||
const packageToBabelConfig = makeWeakCache(
|
||||
(file: ConfigFile): ConfigFile | null => {
|
||||
if (typeof file.options.babel === "undefined") return null;
|
||||
const babel = file.options.babel;
|
||||
const babel = file.options[("babel": string)];
|
||||
|
||||
if (typeof babel === "undefined") return null;
|
||||
|
||||
if (typeof babel !== "object" || Array.isArray(babel) || babel === null) {
|
||||
throw new Error(`${file.filepath}: .babel property must be an object`);
|
||||
|
||||
@@ -174,7 +174,10 @@ const loadDescriptor = makeWeakCache(
|
||||
|
||||
let item = value;
|
||||
if (typeof value === "function") {
|
||||
const api = Object.assign({}, context, makeAPI(cache));
|
||||
const api = {
|
||||
...context,
|
||||
...makeAPI(cache),
|
||||
};
|
||||
try {
|
||||
item = value(api, options, dirname);
|
||||
} catch (e) {
|
||||
@@ -229,9 +232,13 @@ const instantiatePlugin = makeWeakCache(
|
||||
): Plugin => {
|
||||
const pluginObj = validatePluginObject(value);
|
||||
|
||||
const plugin = Object.assign({}, pluginObj);
|
||||
const plugin = {
|
||||
...pluginObj,
|
||||
};
|
||||
if (plugin.visitor) {
|
||||
plugin.visitor = traverse.explode(Object.assign({}, plugin.visitor));
|
||||
plugin.visitor = traverse.explode({
|
||||
...plugin.visitor,
|
||||
});
|
||||
}
|
||||
|
||||
if (plugin.inherits) {
|
||||
|
||||
@@ -17,10 +17,3 @@ export function loadOptions(opts: {}): Object | null {
|
||||
|
||||
return config ? config.options : null;
|
||||
}
|
||||
|
||||
// For easier backward-compatibility, provide an API like the one we exposed in Babel 6.
|
||||
export class OptionManager {
|
||||
init(opts: {}) {
|
||||
return loadOptions(opts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,12 +28,17 @@ export default function loadPrivatePartialConfig(
|
||||
|
||||
const args = inputOpts ? validate("arguments", inputOpts) : {};
|
||||
|
||||
const { envName = getEnv(), cwd = "." } = args;
|
||||
const { envName = getEnv(), cwd = ".", root: rootDir = "." } = args;
|
||||
const absoluteCwd = path.resolve(cwd);
|
||||
const absoluteRootDir = path.resolve(absoluteCwd, rootDir);
|
||||
|
||||
const context: ConfigContext = {
|
||||
filename: args.filename ? path.resolve(cwd, args.filename) : null,
|
||||
filename:
|
||||
typeof args.filename === "string"
|
||||
? path.resolve(cwd, args.filename)
|
||||
: undefined,
|
||||
cwd: absoluteCwd,
|
||||
root: absoluteRootDir,
|
||||
envName,
|
||||
};
|
||||
|
||||
@@ -49,9 +54,13 @@ export default function loadPrivatePartialConfig(
|
||||
// passed back to Babel a second time, it will be in the right structure
|
||||
// to not change behavior.
|
||||
options.babelrc = false;
|
||||
options.envName = envName;
|
||||
options.cwd = absoluteCwd;
|
||||
options.configFile = false;
|
||||
options.passPerPreset = false;
|
||||
options.envName = context.envName;
|
||||
options.cwd = context.cwd;
|
||||
options.root = context.root;
|
||||
options.filename =
|
||||
typeof context.filename === "string" ? context.filename : undefined;
|
||||
|
||||
options.plugins = configChain.plugins.map(descriptor =>
|
||||
createItemFromDescriptor(descriptor),
|
||||
|
||||
@@ -36,12 +36,6 @@ const ROOT_VALIDATORS: ValidatorSet = {
|
||||
filenameRelative: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "filenameRelative">,
|
||||
>),
|
||||
babelrc: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "babelrc">,
|
||||
>),
|
||||
babelrcRoots: (assertBabelrcSearch: Validator<
|
||||
$PropertyType<ValidatedOptions, "babelrcRoots">,
|
||||
>),
|
||||
code: (assertBoolean: Validator<$PropertyType<ValidatedOptions, "code">>),
|
||||
ast: (assertBoolean: Validator<$PropertyType<ValidatedOptions, "ast">>),
|
||||
|
||||
@@ -50,31 +44,23 @@ const ROOT_VALIDATORS: ValidatorSet = {
|
||||
>),
|
||||
};
|
||||
|
||||
const BABELRC_VALIDATORS: ValidatorSet = {
|
||||
babelrc: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "babelrc">,
|
||||
>),
|
||||
babelrcRoots: (assertBabelrcSearch: Validator<
|
||||
$PropertyType<ValidatedOptions, "babelrcRoots">,
|
||||
>),
|
||||
};
|
||||
|
||||
const NONPRESET_VALIDATORS: ValidatorSet = {
|
||||
extends: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "extends">,
|
||||
>),
|
||||
env: (assertEnvSet: Validator<$PropertyType<ValidatedOptions, "env">>),
|
||||
ignore: (assertIgnoreList: Validator<
|
||||
$PropertyType<ValidatedOptions, "ignore">,
|
||||
>),
|
||||
only: (assertIgnoreList: Validator<$PropertyType<ValidatedOptions, "only">>),
|
||||
overrides: (assertOverridesList: Validator<
|
||||
$PropertyType<ValidatedOptions, "overrides">,
|
||||
>),
|
||||
|
||||
// We could limit these to 'overrides' blocks, but it's not clear why we'd
|
||||
// bother, when the ability to limit a config to a specific set of files
|
||||
// is a fairly general useful feature.
|
||||
test: (assertConfigApplicableTest: Validator<
|
||||
$PropertyType<ValidatedOptions, "test">,
|
||||
>),
|
||||
include: (assertConfigApplicableTest: Validator<
|
||||
$PropertyType<ValidatedOptions, "include">,
|
||||
>),
|
||||
exclude: (assertConfigApplicableTest: Validator<
|
||||
$PropertyType<ValidatedOptions, "exclude">,
|
||||
>),
|
||||
};
|
||||
|
||||
const COMMON_VALIDATORS: ValidatorSet = {
|
||||
@@ -93,6 +79,25 @@ const COMMON_VALIDATORS: ValidatorSet = {
|
||||
passPerPreset: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "passPerPreset">,
|
||||
>),
|
||||
|
||||
env: (assertEnvSet: Validator<$PropertyType<ValidatedOptions, "env">>),
|
||||
overrides: (assertOverridesList: Validator<
|
||||
$PropertyType<ValidatedOptions, "overrides">,
|
||||
>),
|
||||
|
||||
// We could limit these to 'overrides' blocks, but it's not clear why we'd
|
||||
// bother, when the ability to limit a config to a specific set of files
|
||||
// is a fairly general useful feature.
|
||||
test: (assertConfigApplicableTest: Validator<
|
||||
$PropertyType<ValidatedOptions, "test">,
|
||||
>),
|
||||
include: (assertConfigApplicableTest: Validator<
|
||||
$PropertyType<ValidatedOptions, "include">,
|
||||
>),
|
||||
exclude: (assertConfigApplicableTest: Validator<
|
||||
$PropertyType<ValidatedOptions, "exclude">,
|
||||
>),
|
||||
|
||||
retainLines: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "retainLines">,
|
||||
>),
|
||||
@@ -243,7 +248,14 @@ export type SourceTypeOption = "module" | "script" | "unambiguous";
|
||||
export type CompactOption = boolean | "auto";
|
||||
export type RootInputSourceMapOption = {} | boolean;
|
||||
|
||||
export type OptionsType = "arguments" | "file" | "env" | "preset" | "override";
|
||||
export type OptionsType =
|
||||
| "arguments"
|
||||
| "env"
|
||||
| "preset"
|
||||
| "override"
|
||||
| "configfile"
|
||||
| "babelrcfile"
|
||||
| "extendsfile";
|
||||
|
||||
export function validate(type: OptionsType, opts: {}): ValidatedOptions {
|
||||
assertNoDuplicateSourcemap(opts);
|
||||
@@ -255,6 +267,22 @@ export function validate(type: OptionsType, opts: {}): ValidatedOptions {
|
||||
if (type !== "arguments" && ROOT_VALIDATORS[key]) {
|
||||
throw new Error(`.${key} is only allowed in root programmatic options`);
|
||||
}
|
||||
if (
|
||||
type !== "arguments" &&
|
||||
type !== "configfile" &&
|
||||
BABELRC_VALIDATORS[key]
|
||||
) {
|
||||
if (type === "babelrcfile" || type === "extendsfile") {
|
||||
throw new Error(
|
||||
`.${key} is not allowed in .babelrc or "extend"ed files, only in root programmatic options, ` +
|
||||
`or babel.config.js/config file options`,
|
||||
);
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`.${key} is only allowed in root programmatic options, or babel.config.js/config file options`,
|
||||
);
|
||||
}
|
||||
if (type === "env" && key === "env") {
|
||||
throw new Error(`.${key} is not allowed inside another env block`);
|
||||
}
|
||||
@@ -268,6 +296,7 @@ export function validate(type: OptionsType, opts: {}): ValidatedOptions {
|
||||
const validator =
|
||||
COMMON_VALIDATORS[key] ||
|
||||
NONPRESET_VALIDATORS[key] ||
|
||||
BABELRC_VALIDATORS[key] ||
|
||||
ROOT_VALIDATORS[key];
|
||||
|
||||
if (validator) validator(key, opts[key]);
|
||||
|
||||
@@ -13,26 +13,22 @@ export * as types from "@babel/types";
|
||||
export { default as traverse } from "@babel/traverse";
|
||||
export { default as template } from "@babel/template";
|
||||
|
||||
export { loadPartialConfig, loadOptions, OptionManager } from "./config";
|
||||
|
||||
export { createConfigItem } from "./config/item";
|
||||
|
||||
export function Plugin(alias: string) {
|
||||
throw new Error(
|
||||
`The (${alias}) Babel 5 plugin is being run with an unsupported Babel version.`,
|
||||
);
|
||||
}
|
||||
export { loadPartialConfig, loadOptions } from "./config";
|
||||
|
||||
export { default as transform } from "./transform";
|
||||
export { default as transformSync } from "./transform-sync";
|
||||
|
||||
export { default as transformFile } from "./transform-file";
|
||||
export { default as transformFileSync } from "./transform-file-sync";
|
||||
|
||||
export { default as transformFromAst } from "./transform-ast";
|
||||
export { default as transformFromAstSync } from "./transform-ast-sync";
|
||||
|
||||
export { default as parse } from "./parse";
|
||||
export { transform, transformSync, transformAsync } from "./transform";
|
||||
export {
|
||||
transformFile,
|
||||
transformFileSync,
|
||||
transformFileAsync,
|
||||
} from "./transform-file";
|
||||
export {
|
||||
transformFromAst,
|
||||
transformFromAstSync,
|
||||
transformFromAstAsync,
|
||||
} from "./transform-ast";
|
||||
export { parse, parseSync, parseAsync } from "./parse";
|
||||
|
||||
/**
|
||||
* Recommended set of compilable extensions. Not used in @babel/core directly, but meant as
|
||||
@@ -45,3 +41,17 @@ export const DEFAULT_EXTENSIONS = Object.freeze([
|
||||
".es",
|
||||
".mjs",
|
||||
]);
|
||||
|
||||
// For easier backward-compatibility, provide an API like the one we exposed in Babel 6.
|
||||
import { loadOptions } from "./config";
|
||||
export class OptionManager {
|
||||
init(opts: {}) {
|
||||
return loadOptions(opts);
|
||||
}
|
||||
}
|
||||
|
||||
export function Plugin(alias: string) {
|
||||
throw new Error(
|
||||
`The (${alias}) Babel 5 plugin is being run with an unsupported Babel version.`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,17 +6,79 @@ import normalizeOptions from "./transformation/normalize-opts";
|
||||
|
||||
type AstRoot = BabelNodeFile | BabelNodeProgram;
|
||||
|
||||
export default function parse(
|
||||
code: string,
|
||||
opts: InputOptions,
|
||||
): AstRoot | null {
|
||||
export type ParseResult = AstRoot;
|
||||
|
||||
export type FileParseCallback = {
|
||||
(Error, null): any,
|
||||
(null, ParseResult | null): any,
|
||||
};
|
||||
|
||||
type Parse = {
|
||||
(code: string, callback: FileParseCallback): void,
|
||||
(code: string, opts: ?InputOptions, callback: FileParseCallback): void,
|
||||
|
||||
// Here for backward-compatibility. Ideally use ".parseSync" if you want
|
||||
// a synchronous API.
|
||||
(code: string, opts: ?InputOptions): ParseResult | null,
|
||||
};
|
||||
|
||||
export const parse: Parse = (function parse(code, opts, callback) {
|
||||
if (typeof opts === "function") {
|
||||
opts = undefined;
|
||||
callback = opts;
|
||||
}
|
||||
|
||||
// For backward-compat with Babel 7's early betas, we allow sync parsing when
|
||||
// no callback is given. Will be dropped in some future Babel major version.
|
||||
if (callback === undefined) return parseSync(code, opts);
|
||||
|
||||
const config = loadConfig(opts);
|
||||
|
||||
if (config === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const file = normalizeFile(config.passes, normalizeOptions(config), code);
|
||||
// Reassign to keep Flowtype happy.
|
||||
const cb = callback;
|
||||
|
||||
return file.ast;
|
||||
// Just delaying the transform one tick for now to simulate async behavior
|
||||
// but more async logic may land here eventually.
|
||||
process.nextTick(() => {
|
||||
let ast = null;
|
||||
try {
|
||||
const cfg = loadConfig(opts);
|
||||
if (cfg === null) return cb(null, null);
|
||||
|
||||
ast = normalizeFile(cfg.passes, normalizeOptions(cfg), code).ast;
|
||||
} catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
cb(null, ast);
|
||||
});
|
||||
}: Function);
|
||||
|
||||
export function parseSync(
|
||||
code: string,
|
||||
opts?: InputOptions,
|
||||
): ParseResult | null {
|
||||
const config = loadConfig(opts);
|
||||
|
||||
if (config === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return normalizeFile(config.passes, normalizeOptions(config), code).ast;
|
||||
}
|
||||
|
||||
export function parseAsync(
|
||||
code: string,
|
||||
opts?: InputOptions,
|
||||
): Promise<ParseResult | null> {
|
||||
return new Promise((res, rej) => {
|
||||
parse(code, opts, (err, result) => {
|
||||
if (err == null) res(result);
|
||||
else rej(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// @flow
|
||||
import loadConfig, { type InputOptions } from "./config";
|
||||
import { runSync, type FileResult } from "./transformation";
|
||||
|
||||
type AstRoot = BabelNodeFile | BabelNodeProgram;
|
||||
|
||||
export default function transformFromAstSync(
|
||||
ast: AstRoot,
|
||||
code: string,
|
||||
opts: ?InputOptions,
|
||||
): FileResult | null {
|
||||
const config = loadConfig(opts);
|
||||
if (config === null) return null;
|
||||
|
||||
if (!ast) throw new Error("No AST given");
|
||||
|
||||
return runSync(config, code, ast);
|
||||
}
|
||||
@@ -2,16 +2,15 @@
|
||||
|
||||
import loadConfig, { type InputOptions } from "./config";
|
||||
import {
|
||||
runSync,
|
||||
runAsync,
|
||||
type FileResult,
|
||||
type FileResultCallback,
|
||||
} from "./transformation";
|
||||
|
||||
import transformAstSync from "./transform-ast-sync";
|
||||
|
||||
type AstRoot = BabelNodeFile | BabelNodeProgram;
|
||||
|
||||
type TransformAst = {
|
||||
type TransformFromAst = {
|
||||
(ast: AstRoot, code: string, callback: FileResultCallback): void,
|
||||
(
|
||||
ast: AstRoot,
|
||||
@@ -25,7 +24,12 @@ type TransformAst = {
|
||||
(ast: AstRoot, code: string, opts: ?InputOptions): FileResult | null,
|
||||
};
|
||||
|
||||
export default ((function transformFromAst(ast, code, opts, callback) {
|
||||
export const transformFromAst: TransformFromAst = (function transformFromAst(
|
||||
ast,
|
||||
code,
|
||||
opts,
|
||||
callback,
|
||||
) {
|
||||
if (typeof opts === "function") {
|
||||
opts = undefined;
|
||||
callback = opts;
|
||||
@@ -33,7 +37,7 @@ export default ((function transformFromAst(ast, code, opts, callback) {
|
||||
|
||||
// For backward-compat with Babel 6, we allow sync transformation when
|
||||
// no callback is given. Will be dropped in some future Babel major version.
|
||||
if (callback === undefined) return transformAstSync(ast, code, opts);
|
||||
if (callback === undefined) return transformFromAstSync(ast, code, opts);
|
||||
|
||||
// Reassign to keep Flowtype happy.
|
||||
const cb = callback;
|
||||
@@ -53,4 +57,30 @@ export default ((function transformFromAst(ast, code, opts, callback) {
|
||||
|
||||
runAsync(cfg, code, ast, cb);
|
||||
});
|
||||
}: Function): TransformAst);
|
||||
}: Function);
|
||||
|
||||
export function transformFromAstSync(
|
||||
ast: AstRoot,
|
||||
code: string,
|
||||
opts: ?InputOptions,
|
||||
): FileResult | null {
|
||||
const config = loadConfig(opts);
|
||||
if (config === null) return null;
|
||||
|
||||
if (!ast) throw new Error("No AST given");
|
||||
|
||||
return runSync(config, code, ast);
|
||||
}
|
||||
|
||||
export function transformFromAstAsync(
|
||||
ast: AstRoot,
|
||||
code: string,
|
||||
opts: ?InputOptions,
|
||||
): Promise<FileResult | null> {
|
||||
return new Promise((res, rej) => {
|
||||
transformFromAst(ast, code, opts, (err, result) => {
|
||||
if (err == null) res(result);
|
||||
else rej(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
// @flow
|
||||
import fs from "fs";
|
||||
|
||||
import loadConfig, { type InputOptions } from "./config";
|
||||
import { runSync, type FileResult } from "./transformation";
|
||||
|
||||
export default function transformFileSync(
|
||||
filename: string,
|
||||
opts: ?InputOptions,
|
||||
): FileResult | null {
|
||||
let options;
|
||||
if (opts == null) {
|
||||
options = { filename };
|
||||
} else if (opts && typeof opts === "object") {
|
||||
options = Object.assign({}, opts, { filename });
|
||||
}
|
||||
|
||||
const config = loadConfig(options);
|
||||
if (config === null) return null;
|
||||
|
||||
return runSync(config, fs.readFileSync(filename, "utf8"));
|
||||
}
|
||||
@@ -2,14 +2,23 @@
|
||||
import fs from "fs";
|
||||
|
||||
import loadConfig, { type InputOptions } from "./config";
|
||||
import { runAsync, type FileResultCallback } from "./transformation";
|
||||
import {
|
||||
runSync,
|
||||
runAsync,
|
||||
type FileResult,
|
||||
type FileResultCallback,
|
||||
} from "./transformation";
|
||||
|
||||
type TransformFile = {
|
||||
(filename: string, callback: FileResultCallback): void,
|
||||
(filename: string, opts: ?InputOptions, callback: FileResultCallback): void,
|
||||
};
|
||||
|
||||
export default ((function transformFile(filename, opts, callback) {
|
||||
export const transformFile: TransformFile = (function transformFile(
|
||||
filename,
|
||||
opts,
|
||||
callback,
|
||||
) {
|
||||
let options;
|
||||
if (typeof opts === "function") {
|
||||
callback = opts;
|
||||
@@ -19,7 +28,10 @@ export default ((function transformFile(filename, opts, callback) {
|
||||
if (opts == null) {
|
||||
options = { filename };
|
||||
} else if (opts && typeof opts === "object") {
|
||||
options = Object.assign({}, opts, { filename });
|
||||
options = {
|
||||
...opts,
|
||||
filename,
|
||||
};
|
||||
}
|
||||
|
||||
process.nextTick(() => {
|
||||
@@ -40,4 +52,36 @@ export default ((function transformFile(filename, opts, callback) {
|
||||
runAsync(config, code, null, callback);
|
||||
});
|
||||
});
|
||||
}: Function): TransformFile);
|
||||
}: Function);
|
||||
|
||||
export function transformFileSync(
|
||||
filename: string,
|
||||
opts: ?InputOptions,
|
||||
): FileResult | null {
|
||||
let options;
|
||||
if (opts == null) {
|
||||
options = { filename };
|
||||
} else if (opts && typeof opts === "object") {
|
||||
options = {
|
||||
...opts,
|
||||
filename,
|
||||
};
|
||||
}
|
||||
|
||||
const config = loadConfig(options);
|
||||
if (config === null) return null;
|
||||
|
||||
return runSync(config, fs.readFileSync(filename, "utf8"));
|
||||
}
|
||||
|
||||
export function transformFileAsync(
|
||||
filename: string,
|
||||
opts: ?InputOptions,
|
||||
): Promise<FileResult | null> {
|
||||
return new Promise((res, rej) => {
|
||||
transformFile(filename, opts, (err, result) => {
|
||||
if (err == null) res(result);
|
||||
else rej(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// @flow
|
||||
import loadConfig, { type InputOptions } from "./config";
|
||||
import { runSync, type FileResult } from "./transformation";
|
||||
|
||||
export default function transformSync(
|
||||
code: string,
|
||||
opts: ?InputOptions,
|
||||
): FileResult | null {
|
||||
const config = loadConfig(opts);
|
||||
if (config === null) return null;
|
||||
|
||||
return runSync(config, code);
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
// @flow
|
||||
import loadConfig, { type InputOptions } from "./config";
|
||||
import {
|
||||
runSync,
|
||||
runAsync,
|
||||
type FileResult,
|
||||
type FileResultCallback,
|
||||
} from "./transformation";
|
||||
|
||||
import transformSync from "./transform-sync";
|
||||
|
||||
type Transform = {
|
||||
(code: string, callback: FileResultCallback): void,
|
||||
(code: string, opts: ?InputOptions, callback: FileResultCallback): void,
|
||||
@@ -17,7 +16,7 @@ type Transform = {
|
||||
(code: string, opts: ?InputOptions): FileResult | null,
|
||||
};
|
||||
|
||||
export default ((function transform(code, opts, callback) {
|
||||
export const transform: Transform = (function transform(code, opts, callback) {
|
||||
if (typeof opts === "function") {
|
||||
opts = undefined;
|
||||
callback = opts;
|
||||
@@ -43,4 +42,26 @@ export default ((function transform(code, opts, callback) {
|
||||
|
||||
runAsync(cfg, code, null, cb);
|
||||
});
|
||||
}: Function): Transform);
|
||||
}: Function);
|
||||
|
||||
export function transformSync(
|
||||
code: string,
|
||||
opts: ?InputOptions,
|
||||
): FileResult | null {
|
||||
const config = loadConfig(opts);
|
||||
if (config === null) return null;
|
||||
|
||||
return runSync(config, code);
|
||||
}
|
||||
|
||||
export function transformAsync(
|
||||
code: string,
|
||||
opts: ?InputOptions,
|
||||
): Promise<FileResult | null> {
|
||||
return new Promise((res, rej) => {
|
||||
transform(code, opts, (err, result) => {
|
||||
if (err == null) res(result);
|
||||
else rej(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,14 +28,12 @@ export default class File {
|
||||
metadata: {} = {};
|
||||
hub: Hub = new Hub(this);
|
||||
code: string = "";
|
||||
shebang: string | null = "";
|
||||
inputMap: Object | null = null;
|
||||
|
||||
constructor(options: {}, { code, ast, shebang, inputMap }: NormalizedFile) {
|
||||
constructor(options: {}, { code, ast, inputMap }: NormalizedFile) {
|
||||
this.opts = options;
|
||||
this.code = code;
|
||||
this.ast = ast;
|
||||
this.shebang = shebang;
|
||||
this.inputMap = inputMap;
|
||||
|
||||
this.path = NodePath.get({
|
||||
@@ -48,6 +46,23 @@ export default class File {
|
||||
this.scope = this.path.scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide backward-compatible access to the interpreter directive handling
|
||||
* in Babel 6.x. If you are writing a plugin for Babel 7.x, it would be
|
||||
* best to use 'program.interpreter' directly.
|
||||
*/
|
||||
get shebang(): string {
|
||||
const { interpreter } = this.path.node;
|
||||
return interpreter ? interpreter.value : "";
|
||||
}
|
||||
set shebang(value: string): void {
|
||||
if (value) {
|
||||
this.path.get("interpreter").replaceWith(t.interpreterDirective(value));
|
||||
} else {
|
||||
this.path.get("interpreter").remove();
|
||||
}
|
||||
}
|
||||
|
||||
set(key: mixed, val: mixed) {
|
||||
this._map.set(key, val);
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
import type { PluginPasses } from "../../config";
|
||||
import convertSourceMap, { type SourceMap } from "convert-source-map";
|
||||
import sourceMap from "source-map";
|
||||
import generate from "@babel/generator";
|
||||
|
||||
import type File from "./file";
|
||||
import mergeSourceMap from "./merge-map";
|
||||
|
||||
export default function generateCode(
|
||||
pluginPasses: PluginPasses,
|
||||
@@ -14,7 +14,7 @@ export default function generateCode(
|
||||
outputCode: string,
|
||||
outputMap: SourceMap | null,
|
||||
} {
|
||||
const { opts, ast, shebang, code, inputMap } = file;
|
||||
const { opts, ast, code, inputMap } = file;
|
||||
|
||||
const results = [];
|
||||
for (const plugins of pluginPasses) {
|
||||
@@ -53,11 +53,6 @@ export default function generateCode(
|
||||
|
||||
let { code: outputCode, map: outputMap } = result;
|
||||
|
||||
if (shebang) {
|
||||
// add back shebang
|
||||
outputCode = `${shebang}\n${outputCode}`;
|
||||
}
|
||||
|
||||
if (outputMap && inputMap) {
|
||||
outputMap = mergeSourceMap(inputMap.toObject(), outputMap);
|
||||
}
|
||||
@@ -72,46 +67,3 @@ export default function generateCode(
|
||||
|
||||
return { outputCode, outputMap };
|
||||
}
|
||||
|
||||
function mergeSourceMap(inputMap: SourceMap, map: SourceMap): SourceMap {
|
||||
const inputMapConsumer = new sourceMap.SourceMapConsumer(inputMap);
|
||||
const outputMapConsumer = new sourceMap.SourceMapConsumer(map);
|
||||
|
||||
const mergedGenerator = new sourceMap.SourceMapGenerator({
|
||||
file: inputMapConsumer.file,
|
||||
sourceRoot: inputMapConsumer.sourceRoot,
|
||||
});
|
||||
|
||||
// This assumes the output map always has a single source, since Babel always compiles a
|
||||
// single source file to a single output file.
|
||||
const source = outputMapConsumer.sources[0];
|
||||
|
||||
inputMapConsumer.eachMapping(function(mapping) {
|
||||
const generatedPosition = outputMapConsumer.generatedPositionFor({
|
||||
line: mapping.generatedLine,
|
||||
column: mapping.generatedColumn,
|
||||
source: source,
|
||||
});
|
||||
if (generatedPosition.column != null) {
|
||||
mergedGenerator.addMapping({
|
||||
source: mapping.source,
|
||||
|
||||
original:
|
||||
mapping.source == null
|
||||
? null
|
||||
: {
|
||||
line: mapping.originalLine,
|
||||
column: mapping.originalColumn,
|
||||
},
|
||||
|
||||
generated: generatedPosition,
|
||||
|
||||
name: mapping.name,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const mergedMap = mergedGenerator.toJSON();
|
||||
inputMap.mappings = mergedMap.mappings;
|
||||
return inputMap;
|
||||
}
|
||||
|
||||
317
packages/babel-core/src/transformation/file/merge-map.js
Normal file
317
packages/babel-core/src/transformation/file/merge-map.js
Normal file
@@ -0,0 +1,317 @@
|
||||
// @flow
|
||||
|
||||
import type { SourceMap } from "convert-source-map";
|
||||
import sourceMap from "source-map";
|
||||
|
||||
export default function mergeSourceMap(
|
||||
inputMap: SourceMap,
|
||||
map: SourceMap,
|
||||
): SourceMap {
|
||||
const input = buildMappingData(inputMap);
|
||||
const output = buildMappingData(map);
|
||||
|
||||
const mergedGenerator = new sourceMap.SourceMapGenerator();
|
||||
for (const { source } of input.sources) {
|
||||
if (typeof source.content === "string") {
|
||||
mergedGenerator.setSourceContent(source.path, source.content);
|
||||
}
|
||||
}
|
||||
|
||||
if (output.sources.length === 1) {
|
||||
const defaultSource = output.sources[0];
|
||||
|
||||
const insertedMappings = new Map();
|
||||
|
||||
// Process each generated range in the input map, e.g. each range over the
|
||||
// code that Babel was originally given.
|
||||
eachInputGeneratedRange(input, (generated, original, source) => {
|
||||
// Then pick out each range over Babel's _output_ that corresponds with
|
||||
// the given range on the code given to Babel.
|
||||
eachOverlappingGeneratedOutputRange(defaultSource, generated, item => {
|
||||
// It's possible that multiple input ranges will overlap the same
|
||||
// generated range. Since sourcemap don't traditionally represent
|
||||
// generated locations with multiple original locations, we explicitly
|
||||
// skip generated locations once we've seen them the first time.
|
||||
const key = makeMappingKey(item);
|
||||
if (insertedMappings.has(key)) return;
|
||||
insertedMappings.set(key, item);
|
||||
|
||||
mergedGenerator.addMapping({
|
||||
source: source.path,
|
||||
original: {
|
||||
line: original.line,
|
||||
column: original.columnStart,
|
||||
},
|
||||
generated: {
|
||||
line: item.line,
|
||||
column: item.columnStart,
|
||||
},
|
||||
name: original.name,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Since mappings are manipulated using single locations, but are interpreted
|
||||
// as ranges, the insertions above may not actually have their ending
|
||||
// locations mapped yet. Here be go through each one and ensure that it has
|
||||
// a well-defined ending location, if one wasn't already created by the start
|
||||
// of a different range.
|
||||
for (const item of insertedMappings.values()) {
|
||||
if (item.columnEnd === Infinity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const clearItem = {
|
||||
line: item.line,
|
||||
columnStart: item.columnEnd,
|
||||
};
|
||||
|
||||
const key = makeMappingKey(clearItem);
|
||||
if (insertedMappings.has(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Insert mappings with no original position to terminate any mappings
|
||||
// that were found above, so that they don't expand beyond their correct
|
||||
// range.
|
||||
mergedGenerator.addMapping({
|
||||
generated: {
|
||||
line: clearItem.line,
|
||||
column: clearItem.columnStart,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const result = mergedGenerator.toJSON();
|
||||
// addMapping expects a relative path, and setSourceContent expects an
|
||||
// absolute path. To avoid this whole confusion, we leave the root out
|
||||
// entirely, and add it at the end here.
|
||||
if (typeof input.sourceRoot === "string") {
|
||||
result.sourceRoot = input.sourceRoot;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function makeMappingKey(item: { line: number, columnStart: number }) {
|
||||
return JSON.stringify([item.line, item.columnStart]);
|
||||
}
|
||||
|
||||
function eachOverlappingGeneratedOutputRange(
|
||||
outputFile: ResolvedFileMappings,
|
||||
inputGeneratedRange: ResolvedGeneratedRange,
|
||||
callback: ResolvedGeneratedRange => mixed,
|
||||
) {
|
||||
// Find the Babel-generated mappings that overlap with this range in the
|
||||
// input sourcemap. Generated locations within the input sourcemap
|
||||
// correspond with the original locations in the map Babel generates.
|
||||
const overlappingOriginal = filterApplicableOriginalRanges(
|
||||
outputFile,
|
||||
inputGeneratedRange,
|
||||
);
|
||||
|
||||
for (const { generated } of overlappingOriginal) {
|
||||
for (const item of generated) {
|
||||
callback(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function filterApplicableOriginalRanges(
|
||||
{ mappings }: ResolvedFileMappings,
|
||||
{ line, columnStart, columnEnd }: ResolvedGeneratedRange,
|
||||
): OriginalMappings {
|
||||
// The mapping array is sorted by original location, so we can
|
||||
// binary-search it for the overlapping ranges.
|
||||
return filterSortedArray(mappings, ({ original: outOriginal }) => {
|
||||
if (line > outOriginal.line) return -1;
|
||||
if (line < outOriginal.line) return 1;
|
||||
|
||||
if (columnStart >= outOriginal.columnEnd) return -1;
|
||||
if (columnEnd <= outOriginal.columnStart) return 1;
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
function eachInputGeneratedRange(
|
||||
map: ResolvedMappings,
|
||||
callback: (
|
||||
ResolvedGeneratedRange,
|
||||
ResolvedOriginalRange,
|
||||
ResolvedSource,
|
||||
) => mixed,
|
||||
) {
|
||||
for (const { source, mappings } of map.sources) {
|
||||
for (const { original, generated } of mappings) {
|
||||
for (const item of generated) {
|
||||
callback(item, original, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ResolvedMappings = {|
|
||||
file: ?string,
|
||||
sourceRoot: ?string,
|
||||
sources: Array<ResolvedFileMappings>,
|
||||
|};
|
||||
type ResolvedFileMappings = {|
|
||||
source: ResolvedSource,
|
||||
mappings: OriginalMappings,
|
||||
|};
|
||||
type OriginalMappings = Array<{|
|
||||
original: ResolvedOriginalRange,
|
||||
generated: Array<ResolvedGeneratedRange>,
|
||||
|}>;
|
||||
type ResolvedSource = {|
|
||||
path: string,
|
||||
content: string | null,
|
||||
|};
|
||||
type ResolvedOriginalRange = {|
|
||||
line: number,
|
||||
columnStart: number,
|
||||
columnEnd: number,
|
||||
name: string | null,
|
||||
|};
|
||||
type ResolvedGeneratedRange = {|
|
||||
line: number,
|
||||
columnStart: number,
|
||||
columnEnd: number,
|
||||
|};
|
||||
|
||||
function buildMappingData(map: SourceMap): ResolvedMappings {
|
||||
const consumer = new sourceMap.SourceMapConsumer({
|
||||
...map,
|
||||
|
||||
// This is a bit hack. .addMapping expects source values to be relative,
|
||||
// but eachMapping returns mappings with absolute paths. To avoid that
|
||||
// incompatibility, we leave the sourceRoot out here and add it to the
|
||||
// final map at the end instead.
|
||||
sourceRoot: null,
|
||||
});
|
||||
|
||||
const sources = new Map();
|
||||
const mappings = new Map();
|
||||
|
||||
let last = null;
|
||||
|
||||
consumer.computeColumnSpans();
|
||||
|
||||
consumer.eachMapping(
|
||||
m => {
|
||||
if (m.originalLine === null) return;
|
||||
|
||||
let source = sources.get(m.source);
|
||||
if (!source) {
|
||||
source = {
|
||||
path: m.source,
|
||||
content: consumer.sourceContentFor(m.source, true),
|
||||
};
|
||||
sources.set(m.source, source);
|
||||
}
|
||||
|
||||
let sourceData = mappings.get(source);
|
||||
if (!sourceData) {
|
||||
sourceData = {
|
||||
source,
|
||||
mappings: [],
|
||||
};
|
||||
mappings.set(source, sourceData);
|
||||
}
|
||||
|
||||
const obj = {
|
||||
line: m.originalLine,
|
||||
columnStart: m.originalColumn,
|
||||
columnEnd: Infinity,
|
||||
name: m.name,
|
||||
};
|
||||
|
||||
if (
|
||||
last &&
|
||||
last.source === source &&
|
||||
last.mapping.line === m.originalLine
|
||||
) {
|
||||
last.mapping.columnEnd = m.originalColumn;
|
||||
}
|
||||
|
||||
last = {
|
||||
source,
|
||||
mapping: obj,
|
||||
};
|
||||
|
||||
sourceData.mappings.push({
|
||||
original: obj,
|
||||
generated: consumer
|
||||
.allGeneratedPositionsFor({
|
||||
source: m.source,
|
||||
line: m.originalLine,
|
||||
column: m.originalColumn,
|
||||
})
|
||||
.map(item => ({
|
||||
line: item.line,
|
||||
columnStart: item.column,
|
||||
// source-map's lastColumn is inclusive, not exclusive, so we need
|
||||
// to add 1 to it.
|
||||
columnEnd: item.lastColumn + 1,
|
||||
})),
|
||||
});
|
||||
},
|
||||
null,
|
||||
sourceMap.SourceMapConsumer.ORIGINAL_ORDER,
|
||||
);
|
||||
|
||||
return {
|
||||
file: map.file,
|
||||
sourceRoot: map.sourceRoot,
|
||||
sources: Array.from(mappings.values()),
|
||||
};
|
||||
}
|
||||
|
||||
function findInsertionLocation<T>(
|
||||
array: Array<T>,
|
||||
callback: T => number,
|
||||
): number {
|
||||
let left = 0;
|
||||
let right = array.length;
|
||||
while (left < right) {
|
||||
const mid = Math.floor((left + right) / 2);
|
||||
const item = array[mid];
|
||||
|
||||
const result = callback(item);
|
||||
if (result === 0) {
|
||||
left = mid;
|
||||
break;
|
||||
}
|
||||
if (result >= 0) {
|
||||
right = mid;
|
||||
} else {
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the value is the start of any set of matches.
|
||||
let i = left;
|
||||
if (i < array.length) {
|
||||
while (i > 0 && callback(array[i]) >= 0) {
|
||||
i--;
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
function filterSortedArray<T>(
|
||||
array: Array<T>,
|
||||
callback: T => number,
|
||||
): Array<T> {
|
||||
const start = findInsertionLocation(array, callback);
|
||||
|
||||
const results = [];
|
||||
for (let i = start; i < array.length && callback(array[i]) === 0; i++) {
|
||||
results.push(array[i]);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
// @flow
|
||||
|
||||
import buildDebug from "debug";
|
||||
import * as t from "@babel/types";
|
||||
import type { PluginPasses } from "../config";
|
||||
import convertSourceMap, { typeof Converter } from "convert-source-map";
|
||||
import { parse } from "babylon";
|
||||
import { parse } from "@babel/parser";
|
||||
import { codeFrameColumns } from "@babel/code-frame";
|
||||
import File from "./file/file";
|
||||
import generateMissingPluginMessage from "./util/missing-plugin-helper";
|
||||
|
||||
const shebangRegex = /^#!.*/;
|
||||
const debug = buildDebug("babel:transform:file");
|
||||
|
||||
export type NormalizedFile = {
|
||||
code: string,
|
||||
ast: {},
|
||||
shebang: string | null,
|
||||
inputMap: Converter | null,
|
||||
};
|
||||
|
||||
@@ -25,23 +25,37 @@ export default function normalizeFile(
|
||||
): File {
|
||||
code = `${code || ""}`;
|
||||
|
||||
let shebang = null;
|
||||
let inputMap = null;
|
||||
if (options.inputSourceMap !== false) {
|
||||
inputMap = convertSourceMap.fromSource(code);
|
||||
if (inputMap) {
|
||||
try {
|
||||
inputMap = convertSourceMap.fromSource(code);
|
||||
|
||||
if (inputMap) {
|
||||
code = convertSourceMap.removeComments(code);
|
||||
}
|
||||
} catch (err) {
|
||||
debug("discarding unknown inline input sourcemap", err);
|
||||
code = convertSourceMap.removeComments(code);
|
||||
} else if (typeof options.inputSourceMap === "object") {
|
||||
}
|
||||
|
||||
if (!inputMap) {
|
||||
try {
|
||||
inputMap = convertSourceMap.fromMapFileSource(code);
|
||||
|
||||
if (inputMap) {
|
||||
code = convertSourceMap.removeMapFileComments(code);
|
||||
}
|
||||
} catch (err) {
|
||||
debug("discarding unknown file input sourcemap", err);
|
||||
code = convertSourceMap.removeMapFileComments(code);
|
||||
}
|
||||
}
|
||||
|
||||
if (!inputMap && typeof options.inputSourceMap === "object") {
|
||||
inputMap = convertSourceMap.fromObject(options.inputSourceMap);
|
||||
}
|
||||
}
|
||||
|
||||
const shebangMatch = shebangRegex.exec(code);
|
||||
if (shebangMatch) {
|
||||
shebang = shebangMatch[0];
|
||||
code = code.replace(shebangRegex, "");
|
||||
}
|
||||
|
||||
if (ast) {
|
||||
if (ast.type === "Program") {
|
||||
ast = t.file(ast, [], []);
|
||||
@@ -49,13 +63,15 @@ export default function normalizeFile(
|
||||
throw new Error("AST root must be a Program or File node");
|
||||
}
|
||||
} else {
|
||||
// The parser's AST types aren't fully compatible with the types generated
|
||||
// by the logic in babel-types.
|
||||
// $FlowFixMe
|
||||
ast = parser(pluginPasses, options, code);
|
||||
}
|
||||
|
||||
return new File(options, {
|
||||
code,
|
||||
ast,
|
||||
shebang,
|
||||
inputMap,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,7 +6,10 @@ import type { ResolvedConfig } from "../config";
|
||||
export default function normalizeOptions(config: ResolvedConfig): {} {
|
||||
const {
|
||||
filename,
|
||||
filenameRelative = filename || "unknown",
|
||||
cwd,
|
||||
filenameRelative = typeof filename === "string"
|
||||
? path.relative(cwd, filename)
|
||||
: "unknown",
|
||||
sourceType = "module",
|
||||
inputSourceMap,
|
||||
sourceMaps = !!inputSourceMap,
|
||||
@@ -14,7 +17,7 @@ export default function normalizeOptions(config: ResolvedConfig): {} {
|
||||
moduleRoot,
|
||||
sourceRoot = moduleRoot,
|
||||
|
||||
sourceFileName = filenameRelative,
|
||||
sourceFileName = path.basename(filenameRelative),
|
||||
|
||||
comments = true,
|
||||
compact = "auto",
|
||||
@@ -22,36 +25,38 @@ export default function normalizeOptions(config: ResolvedConfig): {} {
|
||||
|
||||
const opts = config.options;
|
||||
|
||||
const options = Object.assign({}, opts, {
|
||||
parserOpts: Object.assign(
|
||||
{
|
||||
sourceType:
|
||||
path.extname(filenameRelative) === ".mjs" ? "module" : sourceType,
|
||||
sourceFileName: filename,
|
||||
plugins: [],
|
||||
},
|
||||
opts.parserOpts,
|
||||
),
|
||||
generatorOpts: Object.assign(
|
||||
{
|
||||
// General generator flags.
|
||||
filename,
|
||||
auxiliaryCommentBefore: opts.auxiliaryCommentBefore,
|
||||
auxiliaryCommentAfter: opts.auxiliaryCommentAfter,
|
||||
retainLines: opts.retainLines,
|
||||
comments,
|
||||
shouldPrintComment: opts.shouldPrintComment,
|
||||
compact,
|
||||
minified: opts.minified,
|
||||
const options = {
|
||||
...opts,
|
||||
|
||||
// Source-map generation flags.
|
||||
sourceMaps,
|
||||
sourceRoot,
|
||||
sourceFileName,
|
||||
},
|
||||
opts.generatorOpts,
|
||||
),
|
||||
});
|
||||
parserOpts: {
|
||||
sourceType:
|
||||
path.extname(filenameRelative) === ".mjs" ? "module" : sourceType,
|
||||
|
||||
sourceFileName: filename,
|
||||
plugins: [],
|
||||
...opts.parserOpts,
|
||||
},
|
||||
|
||||
generatorOpts: {
|
||||
// General generator flags.
|
||||
filename,
|
||||
|
||||
auxiliaryCommentBefore: opts.auxiliaryCommentBefore,
|
||||
auxiliaryCommentAfter: opts.auxiliaryCommentAfter,
|
||||
retainLines: opts.retainLines,
|
||||
comments,
|
||||
shouldPrintComment: opts.shouldPrintComment,
|
||||
compact,
|
||||
minified: opts.minified,
|
||||
|
||||
// Source-map generation flags.
|
||||
sourceMaps,
|
||||
|
||||
sourceRoot,
|
||||
sourceFileName,
|
||||
...opts.generatorOpts,
|
||||
},
|
||||
};
|
||||
|
||||
for (const plugins of config.passes) {
|
||||
for (const plugin of plugins) {
|
||||
|
||||
@@ -7,14 +7,20 @@ export default class PluginPass {
|
||||
key: ?string;
|
||||
file: File;
|
||||
opts: Object;
|
||||
|
||||
// The working directory that Babel's programmatic options are loaded
|
||||
// relative to.
|
||||
cwd: string;
|
||||
|
||||
// The absolute path of the file being compiled.
|
||||
filename: string | void;
|
||||
|
||||
constructor(file: File, key: ?string, options: ?Object) {
|
||||
this.key = key;
|
||||
this.file = file;
|
||||
this.opts = options || {};
|
||||
this.filename =
|
||||
typeof file.opts.filename === "string" ? file.opts.filename : undefined;
|
||||
this.cwd = file.opts.cwd;
|
||||
this.filename = file.opts.filename;
|
||||
}
|
||||
|
||||
set(key: mixed, val: mixed) {
|
||||
|
||||
@@ -209,7 +209,7 @@ const getNameURLCombination = ({ name, url }) => `${name} (${url})`;
|
||||
|
||||
/*
|
||||
Returns a string of the format:
|
||||
Support for the experimental syntax [babylon plugin name] isn't currently enabled ([loc]):
|
||||
Support for the experimental syntax [@babel/parser plugin name] isn't currently enabled ([loc]):
|
||||
|
||||
[code frame]
|
||||
|
||||
|
||||
@@ -12,11 +12,35 @@ function assertNotIgnored(result) {
|
||||
expect(result.ignored).toBeFalsy();
|
||||
}
|
||||
|
||||
function transform(code, opts) {
|
||||
return babel.transform(code, {
|
||||
cwd: __dirname,
|
||||
...opts,
|
||||
});
|
||||
}
|
||||
|
||||
function transformFile(filename, opts, cb) {
|
||||
return babel.transformFile(
|
||||
filename,
|
||||
{
|
||||
cwd: __dirname,
|
||||
...opts,
|
||||
},
|
||||
cb,
|
||||
);
|
||||
}
|
||||
function transformFileSync(filename, opts) {
|
||||
return babel.transformFileSync(filename, {
|
||||
cwd: __dirname,
|
||||
...opts,
|
||||
});
|
||||
}
|
||||
|
||||
// shim
|
||||
function transformAsync(code, opts) {
|
||||
return {
|
||||
then: function(resolve) {
|
||||
resolve(babel.transform(code, opts));
|
||||
resolve(transform(code, opts));
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -32,7 +56,7 @@ describe("parser and generator options", function() {
|
||||
};
|
||||
|
||||
function newTransform(string) {
|
||||
return babel.transform(string, {
|
||||
return transform(string, {
|
||||
ast: true,
|
||||
parserOpts: {
|
||||
parser: recast.parse,
|
||||
@@ -48,7 +72,7 @@ describe("parser and generator options", function() {
|
||||
it("options", function() {
|
||||
const string = "original;";
|
||||
expect(newTransform(string).ast).toEqual(
|
||||
babel.transform(string, { ast: true }).ast,
|
||||
transform(string, { ast: true }).ast,
|
||||
);
|
||||
expect(newTransform(string).code).toBe(string);
|
||||
});
|
||||
@@ -57,7 +81,7 @@ describe("parser and generator options", function() {
|
||||
const experimental = "var a: number = 1;";
|
||||
|
||||
expect(newTransform(experimental).ast).toEqual(
|
||||
babel.transform(experimental, {
|
||||
transform(experimental, {
|
||||
ast: true,
|
||||
parserOpts: {
|
||||
plugins: ["flow"],
|
||||
@@ -67,7 +91,7 @@ describe("parser and generator options", function() {
|
||||
expect(newTransform(experimental).code).toBe(experimental);
|
||||
|
||||
function newTransformWithPlugins(string) {
|
||||
return babel.transform(string, {
|
||||
return transform(string, {
|
||||
ast: true,
|
||||
plugins: [__dirname + "/../../babel-plugin-syntax-flow"],
|
||||
parserOpts: {
|
||||
@@ -80,7 +104,7 @@ describe("parser and generator options", function() {
|
||||
}
|
||||
|
||||
expect(newTransformWithPlugins(experimental).ast).toEqual(
|
||||
babel.transform(experimental, {
|
||||
transform(experimental, {
|
||||
ast: true,
|
||||
parserOpts: {
|
||||
plugins: ["flow"],
|
||||
@@ -94,7 +118,7 @@ describe("parser and generator options", function() {
|
||||
const experimental = "if (true) {\n import a from 'a';\n}";
|
||||
|
||||
expect(newTransform(experimental).ast).not.toBe(
|
||||
babel.transform(experimental, {
|
||||
transform(experimental, {
|
||||
ast: true,
|
||||
parserOpts: {
|
||||
allowImportExportEverywhere: true,
|
||||
@@ -123,7 +147,7 @@ describe("api", function() {
|
||||
babelrc: false,
|
||||
};
|
||||
Object.freeze(options);
|
||||
babel.transformFile(__dirname + "/fixtures/api/file.js", options, function(
|
||||
transformFile(__dirname + "/fixtures/api/file.js", options, function(
|
||||
err,
|
||||
res,
|
||||
) {
|
||||
@@ -141,15 +165,14 @@ describe("api", function() {
|
||||
};
|
||||
Object.freeze(options);
|
||||
expect(
|
||||
babel.transformFileSync(__dirname + "/fixtures/api/file.js", options)
|
||||
.code,
|
||||
transformFileSync(__dirname + "/fixtures/api/file.js", options).code,
|
||||
).toBe("foo();");
|
||||
expect(options).toEqual({ babelrc: false });
|
||||
});
|
||||
|
||||
it("options throw on falsy true", function() {
|
||||
return expect(function() {
|
||||
babel.transform("", {
|
||||
transform("", {
|
||||
plugins: [__dirname + "/../../babel-plugin-syntax-jsx", false],
|
||||
});
|
||||
}).toThrow(/.plugins\[1\] must be a string, object, function/);
|
||||
@@ -170,7 +193,7 @@ describe("api", function() {
|
||||
let calledRaw = 0;
|
||||
let calledIntercept = 0;
|
||||
|
||||
babel.transform("function foo() { bar(foobar); }", {
|
||||
transform("function foo() { bar(foobar); }", {
|
||||
wrapPluginVisitorMethod: function(pluginAlias, visitorType, callback) {
|
||||
if (pluginAlias !== "foobar") {
|
||||
return callback;
|
||||
@@ -204,7 +227,7 @@ describe("api", function() {
|
||||
let aliasBaseType = null;
|
||||
|
||||
function execTest(passPerPreset) {
|
||||
return babel.transform("type Foo = number; let x = (y): Foo => y;", {
|
||||
return transform("type Foo = number; let x = (y): Foo => y;", {
|
||||
sourceType: "script",
|
||||
passPerPreset: passPerPreset,
|
||||
presets: [
|
||||
@@ -293,7 +316,7 @@ describe("api", function() {
|
||||
const oldEnv = process.env.BABEL_ENV;
|
||||
process.env.BABEL_ENV = "development";
|
||||
|
||||
const result = babel.transform("", {
|
||||
const result = transform("", {
|
||||
cwd: path.join(__dirname, "fixtures", "config", "complex-plugin-config"),
|
||||
filename: path.join(
|
||||
__dirname,
|
||||
@@ -347,8 +370,62 @@ describe("api", function() {
|
||||
);
|
||||
});
|
||||
|
||||
it("interpreter directive backward-compat", function() {
|
||||
function doTransform(code, preHandler) {
|
||||
return transform(code, {
|
||||
plugins: [
|
||||
{
|
||||
pre: preHandler,
|
||||
},
|
||||
],
|
||||
}).code;
|
||||
}
|
||||
|
||||
// Writes value properly.
|
||||
expect(
|
||||
doTransform("", file => {
|
||||
file.shebang = "env node";
|
||||
}),
|
||||
).toBe(`#!env node`);
|
||||
expect(
|
||||
doTransform("#!env node", file => {
|
||||
file.shebang = "env node2";
|
||||
}),
|
||||
).toBe(`#!env node2`);
|
||||
expect(
|
||||
doTransform("", file => {
|
||||
file.shebang = "";
|
||||
}),
|
||||
).toBe(``);
|
||||
expect(
|
||||
doTransform("#!env node", file => {
|
||||
file.shebang = "";
|
||||
}),
|
||||
).toBe(``);
|
||||
|
||||
// Reads value properly.
|
||||
doTransform("", file => {
|
||||
expect(file.shebang).toBe("");
|
||||
});
|
||||
doTransform("#!env node", file => {
|
||||
expect(file.shebang).toBe("env node");
|
||||
});
|
||||
|
||||
// Reads and writes properly.
|
||||
expect(
|
||||
doTransform("#!env node", file => {
|
||||
expect(file.shebang).toBe("env node");
|
||||
|
||||
file.shebang = "env node2";
|
||||
expect(file.shebang).toBe("env node2");
|
||||
|
||||
file.shebang = "env node3";
|
||||
}),
|
||||
).toBe(`#!env node3`);
|
||||
});
|
||||
|
||||
it("source map merging", function() {
|
||||
const result = babel.transform(
|
||||
const result = transform(
|
||||
[
|
||||
/* eslint-disable max-len */
|
||||
'function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }',
|
||||
@@ -394,6 +471,16 @@ describe("api", function() {
|
||||
});
|
||||
});
|
||||
|
||||
it("default source map filename", function() {
|
||||
return transformAsync("var a = 10;", {
|
||||
cwd: "/some/absolute",
|
||||
filename: "/some/absolute/file/path.js",
|
||||
sourceMaps: true,
|
||||
}).then(function(result) {
|
||||
expect(result.map.sources).toEqual(["path.js"]);
|
||||
});
|
||||
});
|
||||
|
||||
it("code option false", function() {
|
||||
return transformAsync("foo('bar');", { code: false }).then(function(
|
||||
result,
|
||||
@@ -545,7 +632,7 @@ describe("api", function() {
|
||||
});
|
||||
|
||||
it("default", function() {
|
||||
const result = babel.transform("foo;", {
|
||||
const result = transform("foo;", {
|
||||
env: {
|
||||
development: { comments: false },
|
||||
},
|
||||
@@ -556,7 +643,7 @@ describe("api", function() {
|
||||
|
||||
it("BABEL_ENV", function() {
|
||||
process.env.BABEL_ENV = "foo";
|
||||
const result = babel.transform("foo;", {
|
||||
const result = transform("foo;", {
|
||||
env: {
|
||||
foo: { comments: false },
|
||||
},
|
||||
@@ -566,7 +653,7 @@ describe("api", function() {
|
||||
|
||||
it("NODE_ENV", function() {
|
||||
process.env.NODE_ENV = "foo";
|
||||
const result = babel.transform("foo;", {
|
||||
const result = transform("foo;", {
|
||||
env: {
|
||||
foo: { comments: false },
|
||||
},
|
||||
@@ -624,7 +711,7 @@ describe("api", function() {
|
||||
};
|
||||
|
||||
it("only syntax plugin available", function(done) {
|
||||
babel.transformFile(
|
||||
transformFile(
|
||||
__dirname + "/fixtures/api/parsing-errors/only-syntax/file.js",
|
||||
options,
|
||||
function(err) {
|
||||
@@ -641,7 +728,7 @@ describe("api", function() {
|
||||
});
|
||||
|
||||
it("both syntax and transform plugin available", function(done) {
|
||||
babel.transformFile(
|
||||
transformFile(
|
||||
__dirname + "/fixtures/api/parsing-errors/syntax-and-transform/file.js",
|
||||
options,
|
||||
function(err) {
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { loadOptions } from "../lib";
|
||||
import { loadOptions as loadOptionsOrig } from "../lib";
|
||||
|
||||
function fixture(...args) {
|
||||
return path.join(__dirname, "fixtures", "config", ...args);
|
||||
}
|
||||
|
||||
function loadOptions(opts) {
|
||||
return loadOptionsOrig({
|
||||
cwd: __dirname,
|
||||
...opts,
|
||||
});
|
||||
}
|
||||
|
||||
describe("buildConfigChain", function() {
|
||||
describe("test", () => {
|
||||
describe("single", () => {
|
||||
@@ -897,7 +904,9 @@ describe("buildConfigChain", function() {
|
||||
describe("config files", () => {
|
||||
const getDefaults = () => ({
|
||||
babelrc: false,
|
||||
configFile: false,
|
||||
cwd: process.cwd(),
|
||||
root: process.cwd(),
|
||||
envName: "development",
|
||||
passPerPreset: false,
|
||||
plugins: [],
|
||||
@@ -927,8 +936,9 @@ describe("buildConfigChain", function() {
|
||||
}),
|
||||
).toEqual({
|
||||
...getDefaults(),
|
||||
filename,
|
||||
filename: filename,
|
||||
cwd: path.dirname(filename),
|
||||
root: path.dirname(filename),
|
||||
comments: true,
|
||||
});
|
||||
});
|
||||
@@ -938,8 +948,9 @@ describe("buildConfigChain", function() {
|
||||
|
||||
expect(loadOptions({ filename, cwd: path.dirname(filename) })).toEqual({
|
||||
...getDefaults(),
|
||||
filename,
|
||||
filename: filename,
|
||||
cwd: path.dirname(filename),
|
||||
root: path.dirname(filename),
|
||||
comments: true,
|
||||
});
|
||||
});
|
||||
@@ -949,8 +960,9 @@ describe("buildConfigChain", function() {
|
||||
|
||||
expect(loadOptions({ filename, cwd: path.dirname(filename) })).toEqual({
|
||||
...getDefaults(),
|
||||
filename,
|
||||
filename: filename,
|
||||
cwd: path.dirname(filename),
|
||||
root: path.dirname(filename),
|
||||
comments: true,
|
||||
});
|
||||
});
|
||||
@@ -990,8 +1002,9 @@ describe("buildConfigChain", function() {
|
||||
|
||||
expect(loadOptions({ filename, cwd: path.dirname(filename) })).toEqual({
|
||||
...getDefaults(),
|
||||
filename,
|
||||
filename: filename,
|
||||
cwd: path.dirname(filename),
|
||||
root: path.dirname(filename),
|
||||
comments: true,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import traverse from "@babel/traverse";
|
||||
import { parse } from "babylon";
|
||||
import { parse } from "@babel/parser";
|
||||
|
||||
describe("evaluation", function() {
|
||||
function addTest(code, type, value, notConfident) {
|
||||
|
||||
@@ -12,6 +12,11 @@ Object.defineProperty(exports, "__esModule", {
|
||||
|
||||
exports.default = function () {
|
||||
return {
|
||||
plugins: [require('../../../../../babel-plugin-syntax-decorators')]
|
||||
plugins: [
|
||||
[
|
||||
require('../../../../../babel-plugin-syntax-decorators'),
|
||||
{ legacy: true }
|
||||
],
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
exports.__esModule = true;
|
||||
module.exports = function() {
|
||||
return {
|
||||
plugins: [require('../../../../../babel-plugin-syntax-decorators')]
|
||||
plugins: [
|
||||
[
|
||||
require('../../../../../babel-plugin-syntax-decorators'),
|
||||
{ legacy: true }
|
||||
],
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
module.exports = function () {
|
||||
return {
|
||||
plugins: [
|
||||
require('../../../../../babel-plugin-syntax-decorators'),
|
||||
[
|
||||
require('../../../../../babel-plugin-syntax-decorators'),
|
||||
{ legacy: true }
|
||||
],
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
module.exports = function() {
|
||||
return {
|
||||
plugins: [
|
||||
require('../../../../../babel-plugin-syntax-decorators'),
|
||||
[
|
||||
require('../../../../../babel-plugin-syntax-decorators'),
|
||||
{ legacy: true }
|
||||
],
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
{
|
||||
"plugins": ["@babel/syntax-decorators"]
|
||||
"plugins": [
|
||||
["@babel/syntax-decorators", { "legacy": true }]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"column": 0
|
||||
}
|
||||
},
|
||||
"interpreter": null,
|
||||
"sourceType": "module",
|
||||
"body": [
|
||||
{
|
||||
@@ -57,7 +58,7 @@
|
||||
"column": 11
|
||||
}
|
||||
},
|
||||
"callee": {
|
||||
"expression": {
|
||||
"type": "Identifier",
|
||||
"start": 1,
|
||||
"end": 11,
|
||||
|
||||
@@ -3,6 +3,8 @@ var Foo =
|
||||
function (_Bar) {
|
||||
"use strict";
|
||||
|
||||
babelHelpers.inherits(Foo, _Bar);
|
||||
|
||||
function Foo(options) {
|
||||
babelHelpers.classCallCheck(this, Foo);
|
||||
var parentOptions = {};
|
||||
@@ -14,6 +16,5 @@ function (_Bar) {
|
||||
return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this, parentOptions));
|
||||
}
|
||||
|
||||
babelHelpers.inherits(Foo, _Bar);
|
||||
return Foo;
|
||||
}(Bar);
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#!env node
|
||||
var someFirstLine;
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"plugins": ["transform-strict-mode"],
|
||||
"retainLines": true
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#!env node
|
||||
"use strict";var someFirstLine;
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [
|
||||
"HelloWorld.vue"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA",
|
||||
"sourceRoot": "src/components",
|
||||
"sourcesContent": [
|
||||
"<template>\n <div class=\"hello\">\n <h1>{{ msg }}</h1>\n <h2>Essential Links</h2>\n <ul>\n <li>\n <a\n href=\"https://vuejs.org\"\n target=\"_blank\"\n >\n Core Docs\n </a>\n </li>\n <li>\n <a\n href=\"https://forum.vuejs.org\"\n target=\"_blank\"\n >\n Forum\n </a>\n </li>\n <li>\n <a\n href=\"https://chat.vuejs.org\"\n target=\"_blank\"\n >\n Community Chat\n </a>\n </li>\n <li>\n <a\n href=\"https://twitter.com/vuejs\"\n target=\"_blank\"\n >\n Twitter\n </a>\n </li>\n <br>\n <li>\n <a\n href=\"http://vuejs-templates.github.io/webpack/\"\n target=\"_blank\"\n >\n Docs for This Template\n </a>\n </li>\n </ul>\n <h2>Ecosystem</h2>\n <ul>\n <li>\n <a\n href=\"http://router.vuejs.org/\"\n target=\"_blank\"\n >\n vue-router\n </a>\n </li>\n <li>\n <a\n href=\"http://vuex.vuejs.org/\"\n target=\"_blank\"\n >\n vuex\n </a>\n </li>\n <li>\n <a\n href=\"http://vue-loader.vuejs.org/\"\n target=\"_blank\"\n >\n vue-loader\n </a>\n </li>\n <li>\n <a\n href=\"https://github.com/vuejs/awesome-vue\"\n target=\"_blank\"\n >\n awesome-vue\n </a>\n </li>\n </ul>\n </div>\n</template>\n\n<script>\nexport default {\n name: 'HelloWorld',\n data () {\n return {\n msg: 'Welcome to Your Vue.js App'\n }\n }\n}\n</script>\n\n<!-- Add \"scoped\" attribute to limit CSS to this component only -->\n<style scoped>\nh1, h2 {\n font-weight: normal;\n}\nul {\n list-style-type: none;\n padding: 0;\n}\nli {\n display: inline-block;\n margin: 0 10px;\n}\na {\n color: #42b983;\n}\n</style>\n"
|
||||
]
|
||||
}
|
||||
113
packages/babel-core/test/fixtures/transformation/source-maps/input-source-map-complex/input.mjs
vendored
Normal file
113
packages/babel-core/test/fixtures/transformation/source-maps/input-source-map-complex/input.mjs
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
data () {
|
||||
return {
|
||||
msg: 'Welcome to Your Vue.js App'
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"plugins": [
|
||||
"transform-modules-commonjs"
|
||||
]
|
||||
}
|
||||
120
packages/babel-core/test/fixtures/transformation/source-maps/input-source-map-complex/output.js
vendored
Normal file
120
packages/babel-core/test/fixtures/transformation/source-maps/input-source-map-complex/output.js
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
var _default = {
|
||||
name: 'HelloWorld',
|
||||
|
||||
data() {
|
||||
return {
|
||||
msg: 'Welcome to Your Vue.js App'
|
||||
};
|
||||
}
|
||||
|
||||
}; //
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
exports.default = _default;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user