Compare commits
305 Commits
v7.0.0-bet
...
v7.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c313b267f7 | ||
|
|
eb54adb755 | ||
|
|
e0ef50c00f | ||
|
|
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 | ||
|
|
3a2aa9b862 | ||
|
|
c8b57f777a | ||
|
|
b414387bb1 | ||
|
|
0bb71caad3 | ||
|
|
d6dcbdad48 | ||
|
|
8606b76438 | ||
|
|
34d73ebef0 | ||
|
|
890a45216f | ||
|
|
0a257e8972 | ||
|
|
3616137864 | ||
|
|
f8ab9466d3 | ||
|
|
8f24f91166 | ||
|
|
dbdce0e4e4 | ||
|
|
4595c7fdfd | ||
|
|
1f97b91655 | ||
|
|
b0e1e84471 | ||
|
|
f7c26bf2bf | ||
|
|
a67eb25547 | ||
|
|
485e37fcb0 | ||
|
|
f013dab5fb | ||
|
|
e45b58dcb1 | ||
|
|
339dfddca5 | ||
|
|
0cd868a5f2 | ||
|
|
29db23ed87 | ||
|
|
2679d6775c | ||
|
|
96316dcf88 | ||
|
|
42244123e1 | ||
|
|
4b97e837ea | ||
|
|
3299086955 | ||
|
|
2bded404f3 | ||
|
|
21c7ff3f37 | ||
|
|
341bdab90c | ||
|
|
81149a5cc9 | ||
|
|
5166eef103 | ||
|
|
0ee9a4e612 | ||
|
|
858a2c74e7 | ||
|
|
668358c4d0 | ||
|
|
39b05598a0 | ||
|
|
29eafbbf44 | ||
|
|
7a106025ea | ||
|
|
4f1473da3d | ||
|
|
c62b202e6a | ||
|
|
a084339a15 | ||
|
|
d7987fbbd2 | ||
|
|
8a31eabf5e | ||
|
|
80428dec47 | ||
|
|
61ec5ce957 | ||
|
|
1e41f613bb | ||
|
|
a86d14de61 | ||
|
|
a62cfe9045 | ||
|
|
f797454a18 | ||
|
|
ec882be44d | ||
|
|
ecbf0dd53c | ||
|
|
af3d6526e7 | ||
|
|
95894397eb | ||
|
|
b1c9af3f05 | ||
|
|
ec3722b3f9 | ||
|
|
7ae724f553 | ||
|
|
6597a472b3 | ||
|
|
fdd0789936 | ||
|
|
5b1332457c | ||
|
|
3177f05904 | ||
|
|
9dc178df9a | ||
|
|
75bc9422b8 | ||
|
|
bd98041321 | ||
|
|
6a8c4ab433 | ||
|
|
637bfe76b1 | ||
|
|
3f72f1d637 | ||
|
|
20de23f895 | ||
|
|
d17adf40df | ||
|
|
450a1678f2 | ||
|
|
e9ed0f5f21 | ||
|
|
29d249e3b7 | ||
|
|
6f9b0546ef | ||
|
|
fa2c6c5164 | ||
|
|
43040a4181 | ||
|
|
01f4c2368e | ||
|
|
56cb4baf46 | ||
|
|
b051243a63 | ||
|
|
e808b63c15 |
@@ -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;
|
||||
};
|
||||
@@ -18,11 +18,6 @@ aliases:
|
||||
- ~/.yarn-cache
|
||||
key: v1-yarn-cache
|
||||
|
||||
- &yarn-install
|
||||
run: |
|
||||
sudo npm i -g yarn@^1.5.1
|
||||
yarn --version
|
||||
|
||||
- &artifact_babel
|
||||
path: ~/babel/packages/babel-standalone/babel.js
|
||||
|
||||
@@ -39,12 +34,12 @@ jobs:
|
||||
build:
|
||||
working_directory: ~/babel
|
||||
docker:
|
||||
- image: circleci/node:9
|
||||
- image: circleci/node:10
|
||||
steps:
|
||||
- checkout
|
||||
- restore-cache: *restore-yarn-cache
|
||||
- restore-cache: *restore-node-modules-cache
|
||||
- *yarn-install
|
||||
- run: yarn --version
|
||||
- run: make test-ci-coverage
|
||||
# Builds babel-standalone with the regular Babel config
|
||||
- run: make build
|
||||
@@ -58,4 +53,4 @@ jobs:
|
||||
- store_artifacts: *artifact_env
|
||||
- store_artifacts: *artifact_env_min
|
||||
- save_cache: *save-node-modules-cache
|
||||
- save_cache: *save-yarn-cache
|
||||
- save_cache: *save-yarn-cache
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/lib
|
||||
/build
|
||||
/.git
|
||||
package.json
|
||||
lerna.json
|
||||
packages/babel-runtime
|
||||
!packages/babel-runtime/scripts
|
||||
!packages/babel-runtime/core-js.js
|
||||
@@ -20,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://slack.babeljs.io/
|
||||
* 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
|
||||
|
||||
16
.travis.yml
16
.travis.yml
@@ -5,12 +5,12 @@ language: node_js
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- node_modules
|
||||
- node_modules
|
||||
node_js:
|
||||
# We test the latest version on circleci
|
||||
- '9'
|
||||
- '8'
|
||||
- '6'
|
||||
- '4'
|
||||
|
||||
env:
|
||||
global:
|
||||
@@ -23,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
|
||||
@@ -38,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,23 +24,24 @@ 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
|
||||
- When you feel ready to jump into the Babel source code, a good place to start is to look for issues tagged with [help wanted](https://github.com/babel/babel/labels/help%20wanted) and/or [good first issue](https://github.com/babel/babel/labels/good%20first%20issue).
|
||||
- Follow along with what we are working on by joining our Slack, following our announcements on [Twitter](https://twitter.com/babeljs), and reading (or participating!) in our [meeting notes](https://github.com/babel/notes).
|
||||
- Follow along with what we are working on by joining our [Slack](https://babeljs.slack.com) (you can sign-up [here](https://slack.babeljs.io/)
|
||||
for an invite), following our announcements on [Twitter](https://twitter.com/babeljs), and reading (or participating!) in our [meeting notes](https://github.com/babel/notes).
|
||||
- Check out our [website](http://babeljs.io/) and the [repo](https://github.com/babel/website)
|
||||
|
||||
## Chat
|
||||
|
||||
Feel free to check out the `#discussion`/`#development` channels on our [Slack](https://slack.babeljs.io). Some of us are always online to chat!
|
||||
Feel free to check out the `#discussion`/`#development` channels on our [Slack](https://slack.babeljs.io) (you can sign-up [here](https://slack.babeljs.io/) for an invite). Some of us are always online to chat!
|
||||
|
||||
## Developing
|
||||
|
||||
**Note:** Versions `< 5.1.10` can't be built.
|
||||
|
||||
Babel is built for Node 4 and up but we develop using Node 8 and yarn. You can check this with `node -v`.
|
||||
Babel is built for Node 6 and up but we develop using Node 8 and yarn. You can check this with `node -v`.
|
||||
|
||||
Make sure that Yarn is installed with version >= `0.28.0`.
|
||||
Installation instructions can be found here: https://yarnpkg.com/en/docs/install.
|
||||
@@ -139,6 +140,12 @@ $ TEST_DEBUG=true make test
|
||||
|
||||
You can combine `TEST_DEBUG` with `TEST_GREP` or `TEST_ONLY` to debug a subset of tests. If you plan to stay long in the debugger (which you'll likely do!), you may increase the test timeout by editing [test/mocha.opts](https://github.com/babel/babel/blob/master/test/mocha.opts).
|
||||
|
||||
To overwrite any test fixtures when fixing a bug or anything, add the env variable `OVERWRITE=true`
|
||||
|
||||
```sh
|
||||
$ OVERWRITE=true TEST_ONLY=babel-plugin-transform-classes make test-only
|
||||
```
|
||||
|
||||
To test the code coverage, use:
|
||||
|
||||
```sh
|
||||
@@ -196,8 +203,8 @@ In an `exec.js` test, we run or check that the code actually does what it's supp
|
||||
|
||||
```js
|
||||
// exec.js
|
||||
assert.equal(8, 2 ** 3);
|
||||
assert.equal(24, 3 * 2 ** 3);
|
||||
expect(2 ** 3).toBe(8);
|
||||
expect(3 * 2 ** 3).toBe(24);
|
||||
```
|
||||
|
||||
If you need to check for an error that is thrown you can add to the `options.json`
|
||||
@@ -219,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
|
||||
@@ -240,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
|
||||
@@ -302,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 = 622bbc4f07acb77eb1109830c70815f827401d90
|
||||
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)))
|
||||
|
||||
170
README.md
170
README.md
@@ -24,108 +24,12 @@
|
||||
<a href="https://medium.com/friendship-dot-js/i-peeked-into-my-node-modules-directory-and-you-wont-believe-what-happened-next-b89f63d21558"><img alt="Business Strategy Status" src="https://img.shields.io/badge/business%20model-flavortown-green.svg"></a>
|
||||
</p>
|
||||
|
||||
Babel is community-driven and thus mostly maintained by a group of [volunteers](https://babeljs.io/team). It has a lot of [companies and projects](https://babeljs.io/users) using it but almost no sponsors/people funded to work on it. If you'd like to help maintain the future of the project, please consider:
|
||||
Babel is a community-driven project used by many companies and projects, and is maintained by a group of [volunteers](https://babeljs.io/team). If you'd like to help support the future of the project, please consider:
|
||||
|
||||
- Giving developer time on the project. (Message us on [Twitter](https://twitter.com/babeljs) or [Slack](https://slack.babeljs.io/))
|
||||
- [Giving funds by becoming a backer/sponsor on OpenCollective](https://opencollective.com/babel)
|
||||
- Giving developer time on the project. (Message us on [Twitter](https://twitter.com/babeljs) or [Slack](https://slack.babeljs.io/) for guidance!)
|
||||
- Giving funds by becoming a sponsor (see below)!
|
||||
|
||||
## Intro
|
||||
|
||||
Babel is a tool that helps you write code in the latest version of JavaScript. When your supported environments don't support certain features natively, Babel will help you compile those features down to a supported version.
|
||||
|
||||
**In**
|
||||
|
||||
```js
|
||||
// ES2015 arrow function
|
||||
[1, 2, 3].map((n) => n + 1);
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```js
|
||||
[1, 2, 3].map(function(n) {
|
||||
return n + 1;
|
||||
});
|
||||
```
|
||||
|
||||
Try it out at our [REPL](https://babeljs.io/repl/build/master#?code_lz=NoRgNATGDMC6B0BbAhgBwBQDsAEBeAfNjgNTYgCUA3EA&lineWrap=true&presets=es2015%2Ces2016%2Ces2017&version=7.0.0-beta.2).
|
||||
|
||||
- [FAQ](#faq)
|
||||
- [Backers](#backers)
|
||||
- [Sponsors](#sponsors)
|
||||
- [License](#license)
|
||||
|
||||
## FAQ
|
||||
|
||||
### Who maintains Babel?
|
||||
|
||||
Mostly a handful of volunteers! Please check out our [team page](https://babeljs.io/team)!
|
||||
|
||||
### Looking for support?
|
||||
|
||||
For questions and support please visit join our [Slack Community](https://slack.babeljs.io/), ask a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/babeljs), or ping us on [Twitter](https://twitter.com/babeljs).
|
||||
|
||||
### Is there a Babel song?
|
||||
|
||||
I'm so glad you asked: [Hallelujah —— In Praise of Babel](SONG.md) by [@angus-c](https://github.com/angus-c). Tweet us your recordings!
|
||||
|
||||
### Where are the docs?
|
||||
|
||||
Check out our website: [babeljs.io](https://babeljs.io/), and report issues/features at [babel/website](https://github.com/babel/website/issues).
|
||||
|
||||
### Want to report a bug or request a feature?
|
||||
|
||||
Please read through our [CONTRIBUTING.md](CONTRIBUTING.md) and fill out the issue template at [babel/issues](https://github.com/babel/babel/issues)!
|
||||
|
||||
### Want to contribute to Babel?
|
||||
|
||||
Check out our [CONTRIBUTING.md](CONTRIBUTING.md) to get started with setting up the repo.
|
||||
|
||||
- If you have already joined Slack, join our [#development](https://babeljs.slack.com/messages/development) channel and say hi!
|
||||
- Check out the issues with the [good first issue](https://github.com/babel/babel/labels/good%20first%20issue) and [help wanted](https://github.com/babel/babel/labels/help%20wanted) label. We suggest also looking at the closed ones to get a sense of the kinds of issues you can tackle.
|
||||
- Our discussions/notes/roadmap: [babel/notes](https://github.com/babel/notes)
|
||||
- Our progress on TC39 proposals: [babel/proposals](https://github.com/babel/proposals)
|
||||
|
||||
### How is the repo structured?
|
||||
|
||||
The Babel repo is managed as a [monorepo](doc/design/monorepo.md) that is composed of many [npm packages](packages/README.md).
|
||||
|
||||
## Backers
|
||||
|
||||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/babel#backer)]
|
||||
|
||||
<a href="https://opencollective.com/babel/backer/0/website" target="_blank"><img src="https://opencollective.com/babel/backer/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/1/website" target="_blank"><img src="https://opencollective.com/babel/backer/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/2/website" target="_blank"><img src="https://opencollective.com/babel/backer/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/3/website" target="_blank"><img src="https://opencollective.com/babel/backer/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/4/website" target="_blank"><img src="https://opencollective.com/babel/backer/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/5/website" target="_blank"><img src="https://opencollective.com/babel/backer/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/6/website" target="_blank"><img src="https://opencollective.com/babel/backer/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/7/website" target="_blank"><img src="https://opencollective.com/babel/backer/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/8/website" target="_blank"><img src="https://opencollective.com/babel/backer/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/9/website" target="_blank"><img src="https://opencollective.com/babel/backer/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/10/website" target="_blank"><img src="https://opencollective.com/babel/backer/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/11/website" target="_blank"><img src="https://opencollective.com/babel/backer/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/12/website" target="_blank"><img src="https://opencollective.com/babel/backer/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/13/website" target="_blank"><img src="https://opencollective.com/babel/backer/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/14/website" target="_blank"><img src="https://opencollective.com/babel/backer/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/15/website" target="_blank"><img src="https://opencollective.com/babel/backer/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/16/website" target="_blank"><img src="https://opencollective.com/babel/backer/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/17/website" target="_blank"><img src="https://opencollective.com/babel/backer/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/18/website" target="_blank"><img src="https://opencollective.com/babel/backer/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/19/website" target="_blank"><img src="https://opencollective.com/babel/backer/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/20/website" target="_blank"><img src="https://opencollective.com/babel/backer/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/21/website" target="_blank"><img src="https://opencollective.com/babel/backer/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/22/website" target="_blank"><img src="https://opencollective.com/babel/backer/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/23/website" target="_blank"><img src="https://opencollective.com/babel/backer/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/24/website" target="_blank"><img src="https://opencollective.com/babel/backer/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/25/website" target="_blank"><img src="https://opencollective.com/babel/backer/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/26/website" target="_blank"><img src="https://opencollective.com/babel/backer/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/27/website" target="_blank"><img src="https://opencollective.com/babel/backer/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/28/website" target="_blank"><img src="https://opencollective.com/babel/backer/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/backer/29/website" target="_blank"><img src="https://opencollective.com/babel/backer/29/avatar.svg"></a>
|
||||
|
||||
## Sponsors
|
||||
## Open Collective Sponsors
|
||||
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/babel#sponsor)]
|
||||
|
||||
@@ -160,6 +64,72 @@ Become a sponsor and get your logo on our README on Github with a link to your s
|
||||
<a href="https://opencollective.com/babel/sponsor/28/website" target="_blank"><img src="https://opencollective.com/babel/sponsor/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/babel/sponsor/29/website" target="_blank"><img src="https://opencollective.com/babel/sponsor/29/avatar.svg"></a>
|
||||
|
||||
## Patreon Sponsors
|
||||
|
||||
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)]
|
||||
|
||||
## Bronze
|
||||
|
||||
<a href="http://teamextension.io/" target="_blank"><img src="https://teamextension.io/dist/img/logo/te-logo-compact.png" height="64"></a>
|
||||
<a href="https://webflow.com/" target="_blank"><img src="https://opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F4a5024b0-8cf2-11e7-b1a2-b30b1de1463c.png&height=64"></a>
|
||||
<p><a href="https://twitter.com/mikesherov">Mike Sherov</a></p>
|
||||
|
||||
## Intro
|
||||
|
||||
Babel is a tool that helps you write code in the latest version of JavaScript. When your supported environments don't support certain features natively, Babel will help you compile those features down to a supported version.
|
||||
|
||||
**In**
|
||||
|
||||
```js
|
||||
// ES2015 arrow function
|
||||
[1, 2, 3].map((n) => n + 1);
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```js
|
||||
[1, 2, 3].map(function(n) {
|
||||
return n + 1;
|
||||
});
|
||||
```
|
||||
|
||||
Try it out at our [REPL](https://babeljs.io/repl/build/master#?code_lz=NoRgNATGDMC6B0BbAhgBwBQDsAEBeAfNjgNTYgCUA3EA&lineWrap=true&presets=es2015%2Ces2016%2Ces2017&version=7.0.0-beta.2).
|
||||
|
||||
## FAQ
|
||||
|
||||
### Who maintains Babel?
|
||||
|
||||
Mostly a handful of volunteers! Please check out our [team page](https://babeljs.io/team)!
|
||||
|
||||
### Looking for support?
|
||||
|
||||
For questions and support please visit join our [Slack Community](https://slack.babeljs.io/) (you can sign-up [here](https://slack.babeljs.io/) for an invite), ask a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/babeljs), or ping us on [Twitter](https://twitter.com/babeljs).
|
||||
|
||||
### Is there a Babel song?
|
||||
|
||||
I'm so glad you asked: [Hallelujah —— In Praise of Babel](SONG.md) by [@angus-c](https://github.com/angus-c). Tweet us your recordings!
|
||||
|
||||
### Where are the docs?
|
||||
|
||||
Check out our website: [babeljs.io](https://babeljs.io/), and report issues/features at [babel/website](https://github.com/babel/website/issues).
|
||||
|
||||
### Want to report a bug or request a feature?
|
||||
|
||||
Please read through our [CONTRIBUTING.md](CONTRIBUTING.md) and fill out the issue template at [babel/issues](https://github.com/babel/babel/issues)!
|
||||
|
||||
### Want to contribute to Babel?
|
||||
|
||||
Check out our [CONTRIBUTING.md](CONTRIBUTING.md) to get started with setting up the repo.
|
||||
|
||||
- If you have already joined Slack, join our [#development](https://babeljs.slack.com/messages/development) channel and say hi!
|
||||
- Check out the issues with the [good first issue](https://github.com/babel/babel/labels/good%20first%20issue) and [help wanted](https://github.com/babel/babel/labels/help%20wanted) label. We suggest also looking at the closed ones to get a sense of the kinds of issues you can tackle.
|
||||
- Our discussions/notes/roadmap: [babel/notes](https://github.com/babel/notes)
|
||||
- Our progress on TC39 proposals: [babel/proposals](https://github.com/babel/proposals)
|
||||
|
||||
### How is the repo structured?
|
||||
|
||||
The Babel repo is managed as a [monorepo](doc/design/monorepo.md) that is composed of many [npm packages](packages/README.md).
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
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.51",
|
||||
"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.51"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": ">=7.0.0-beta.50 <7.0.0-rc.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.0.0-beta.51",
|
||||
"@babel/helper-plugin-test-runner": "7.0.0-beta.51"
|
||||
},
|
||||
"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.44",
|
||||
"version": "7.0.0-beta.51",
|
||||
"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.44"
|
||||
"@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.51"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "7.0.0-beta.44"
|
||||
"@babel/core": ">=7.0.0-beta.50 <7.0.0-rc.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.0.0-beta.44",
|
||||
"@babel/helper-plugin-test-runner": "7.0.0-beta.44"
|
||||
"@babel/core": "7.0.0-beta.51",
|
||||
"@babel/helper-plugin-test-runner": "7.0.0-beta.51"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
The Babel compiler is **only** supported in these environments:
|
||||
|
||||
- Modern browsers such as Chrome, Firefox, Safari, Edge etc.
|
||||
- Node.js 4 and upper versions
|
||||
- Node.js 6 and newer versions
|
||||
|
||||
## Unsupported environments
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"lerna": "2.0.0-rc.4",
|
||||
"version": "7.0.0-beta.44",
|
||||
"lerna": "2.11.0",
|
||||
"version": "7.0.0-beta.51",
|
||||
"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,
|
||||
};
|
||||
}
|
||||
|
||||
42
package.json
42
package.json
@@ -10,22 +10,20 @@
|
||||
"test": "make test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.0.0-beta.42",
|
||||
"@babel/core": "7.0.0-beta.42",
|
||||
"@babel/plugin-transform-modules-commonjs": "7.0.0-beta.42",
|
||||
"@babel/preset-env": "7.0.0-beta.42",
|
||||
"@babel/preset-flow": "7.0.0-beta.42",
|
||||
"@babel/preset-stage-0": "7.0.0-beta.42",
|
||||
"@babel/register": "7.0.0-beta.42",
|
||||
"@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.42",
|
||||
"browserify": "^13.1.1",
|
||||
"bundle-collapser": "^1.2.1",
|
||||
"chai": "^4.1.0",
|
||||
"chalk": "^2.3.2",
|
||||
"charcodes": "^0.1.0",
|
||||
"derequire": "^2.0.2",
|
||||
@@ -33,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",
|
||||
@@ -44,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",
|
||||
@@ -69,7 +67,7 @@
|
||||
"webpack-stream": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.x <= 9.x",
|
||||
"node": ">= 6.9.0 <= 11.0.0-0",
|
||||
"npm": ">= 2.x <= 5.x",
|
||||
"yarn": ">=0.27.5 || >=1.0.0-20170811"
|
||||
},
|
||||
@@ -90,7 +88,7 @@
|
||||
"/node_modules/",
|
||||
"/test/fixtures/",
|
||||
"/test/debug-fixtures/",
|
||||
"/babylon/test/expressions/",
|
||||
"/babel-parser/test/expressions/",
|
||||
"/test/tmp/",
|
||||
"/test/__data__/",
|
||||
"/test/helpers/",
|
||||
@@ -107,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.44",
|
||||
"version": "7.0.0-beta.51",
|
||||
"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.44"
|
||||
"@babel/core": ">=7.0.0-beta.50 <7.0.0-rc.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.0.0-beta.44",
|
||||
"@babel/helper-fixtures": "7.0.0-beta.44"
|
||||
"@babel/core": "7.0.0-beta.51",
|
||||
"@babel/helper-fixtures": "7.0.0-beta.51"
|
||||
},
|
||||
"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,269 +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();
|
||||
//the configFile CLI option maps to the extends option in the node API
|
||||
if (opts.configFile) {
|
||||
opts.extends = opts.configFile;
|
||||
}
|
||||
|
||||
// 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.configFile;
|
||||
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,13 +1,10 @@
|
||||
const includes = require("lodash/includes");
|
||||
const readdir = require("fs-readdir-recursive");
|
||||
const helper = require("@babel/helper-fixtures");
|
||||
const assert = require("assert");
|
||||
const rimraf = require("rimraf");
|
||||
const outputFileSync = require("output-file-sync");
|
||||
const child = require("child_process");
|
||||
const merge = require("lodash/merge");
|
||||
const path = require("path");
|
||||
const chai = require("chai");
|
||||
const fs = require("fs");
|
||||
|
||||
const fixtureLoc = path.join(__dirname, "fixtures");
|
||||
@@ -39,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];
|
||||
@@ -47,21 +46,28 @@ 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) {
|
||||
assert.ok(
|
||||
includes(stderr, expectStderr),
|
||||
"stderr " +
|
||||
JSON.stringify(stderr) +
|
||||
" didn't contain " +
|
||||
JSON.stringify(expectStderr),
|
||||
);
|
||||
expect(stderr).toContain(expectStderr);
|
||||
} else {
|
||||
chai.expect(stderr).to.equal(expectStderr, "stderr didn't match");
|
||||
expect(stderr).toBe(expectStderr);
|
||||
}
|
||||
} else if (stderr) {
|
||||
throw new Error("stderr:\n" + stderr);
|
||||
@@ -73,15 +79,9 @@ const assertTest = function(stdout, stderr, opts) {
|
||||
|
||||
if (opts.stdout) {
|
||||
if (opts.stdoutContains) {
|
||||
assert.ok(
|
||||
includes(stdout, expectStdout),
|
||||
"stdout " +
|
||||
JSON.stringify(stdout) +
|
||||
" didn't contain " +
|
||||
JSON.stringify(expectStdout),
|
||||
);
|
||||
expect(stdout).toContain(expectStdout);
|
||||
} else {
|
||||
chai.expect(stdout).to.equal(expectStdout, "stdout didn't match");
|
||||
expect(stdout).toBe(expectStdout);
|
||||
}
|
||||
} else if (stdout) {
|
||||
throw new Error("stdout:\n" + stdout);
|
||||
@@ -96,24 +96,19 @@ const assertTest = function(stdout, stderr, opts) {
|
||||
filename !== ".babelrc" &&
|
||||
!opts.inFiles.hasOwnProperty(filename)
|
||||
) {
|
||||
const expect = opts.outFiles[filename];
|
||||
const expected = opts.outFiles[filename];
|
||||
const actual = actualFiles[filename];
|
||||
|
||||
chai.expect(expect, "Output is missing: " + filename).to.not.be
|
||||
.undefined;
|
||||
expect(expected).not.toBeUndefined();
|
||||
|
||||
if (expect) {
|
||||
chai
|
||||
.expect(actual)
|
||||
.to.equal(expect, "Compiled output does not match: " + filename);
|
||||
if (expected) {
|
||||
expect(actual).toBe(expected);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(opts.outFiles).forEach(function(filename) {
|
||||
chai
|
||||
.expect(actualFiles, "Extraneous file in output: " + filename)
|
||||
.to.contain.key(filename);
|
||||
expect(actualFiles).toHaveProperty([filename]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -156,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.44",
|
||||
"version": "7.0.0-beta.51",
|
||||
"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.44"
|
||||
"@babel/highlight": "7.0.0-beta.51"
|
||||
},
|
||||
"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,246 +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` | `true` | 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 |
|
||||
| `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) |
|
||||
| `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.44",
|
||||
"version": "7.0.0-beta.51",
|
||||
"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.44",
|
||||
"@babel/generator": "7.0.0-beta.44",
|
||||
"@babel/helpers": "7.0.0-beta.44",
|
||||
"@babel/template": "7.0.0-beta.44",
|
||||
"@babel/traverse": "7.0.0-beta.44",
|
||||
"@babel/types": "7.0.0-beta.44",
|
||||
"babylon": "7.0.0-beta.44",
|
||||
"@babel/code-frame": "7.0.0-beta.51",
|
||||
"@babel/generator": "7.0.0-beta.51",
|
||||
"@babel/helpers": "7.0.0-beta.51",
|
||||
"@babel/parser": "7.0.0-beta.51",
|
||||
"@babel/template": "7.0.0-beta.51",
|
||||
"@babel/traverse": "7.0.0-beta.51",
|
||||
"@babel/types": "7.0.0-beta.51",
|
||||
"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.44",
|
||||
"@babel/register": "7.0.0-beta.44"
|
||||
"@babel/helper-transform-fixture-test-runner": "7.0.0-beta.51",
|
||||
"@babel/register": "7.0.0-beta.51"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,15 +8,19 @@ import {
|
||||
type ValidatedOptions,
|
||||
type IgnoreList,
|
||||
type ConfigApplicableTest,
|
||||
type BabelrcSearch,
|
||||
} from "./validation/options";
|
||||
|
||||
const debug = buildDebug("babel:config:config-chain");
|
||||
|
||||
import {
|
||||
findPackageData,
|
||||
findRelativeConfig,
|
||||
findRootConfig,
|
||||
loadConfig,
|
||||
type ConfigFile,
|
||||
type IgnoreFile,
|
||||
type FilePackageData,
|
||||
} from "./files";
|
||||
|
||||
import { makeWeakCache, makeStrongCache } from "./caching";
|
||||
@@ -42,8 +46,9 @@ export type PresetInstance = {
|
||||
};
|
||||
|
||||
export type ConfigContext = {
|
||||
filename: string | null,
|
||||
filename: string | void,
|
||||
cwd: string,
|
||||
root: string,
|
||||
envName: string,
|
||||
};
|
||||
|
||||
@@ -106,6 +111,7 @@ const loadPresetOverridesEnvDescriptors = makeWeakCache(
|
||||
|
||||
export type RootConfigChain = ConfigChain & {
|
||||
babelrc: ConfigFile | void,
|
||||
config: ConfigFile | void,
|
||||
ignore: IgnoreFile | void,
|
||||
};
|
||||
|
||||
@@ -125,24 +131,60 @@ export function buildRootChain(
|
||||
);
|
||||
if (!programmaticChain) return null;
|
||||
|
||||
let ignore, babelrc;
|
||||
let configFile;
|
||||
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 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);
|
||||
}
|
||||
|
||||
const pkgData =
|
||||
typeof context.filename === "string"
|
||||
? findPackageData(context.filename)
|
||||
: null;
|
||||
|
||||
let ignoreFile, babelrcFile;
|
||||
const fileChain = emptyChain();
|
||||
// resolve all .babelrc files
|
||||
if (opts.babelrc !== false && context.filename !== null) {
|
||||
const filename = context.filename;
|
||||
|
||||
({ ignore, config: babelrc } = findRelativeConfig(
|
||||
filename,
|
||||
if (
|
||||
(babelrc === true || babelrc === undefined) &&
|
||||
pkgData &&
|
||||
babelrcLoadEnabled(context, pkgData, babelrcRoots)
|
||||
) {
|
||||
({ ignore: ignoreFile, config: babelrcFile } = findRelativeConfig(
|
||||
pkgData,
|
||||
context.envName,
|
||||
));
|
||||
|
||||
if (ignore && shouldIgnore(context, ignore.ignore, null, ignore.dirname)) {
|
||||
if (
|
||||
ignoreFile &&
|
||||
shouldIgnore(context, ignoreFile.ignore, null, ignoreFile.dirname)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (babelrc) {
|
||||
const result = loadFileChain(babelrc, context);
|
||||
if (babelrcFile) {
|
||||
const result = loadFileChain(validateBabelrcFile(babelrcFile), context);
|
||||
if (!result) return null;
|
||||
|
||||
mergeChain(fileChain, result);
|
||||
@@ -152,7 +194,7 @@ export function buildRootChain(
|
||||
// Insert file chain in front so programmatic options have priority
|
||||
// over configuration file chain items.
|
||||
const chain = mergeChain(
|
||||
mergeChain(emptyChain(), fileChain),
|
||||
mergeChain(mergeChain(emptyChain(), configFileChain), fileChain),
|
||||
programmaticChain,
|
||||
);
|
||||
|
||||
@@ -160,16 +202,68 @@ export function buildRootChain(
|
||||
plugins: dedupDescriptors(chain.plugins),
|
||||
presets: dedupDescriptors(chain.presets),
|
||||
options: chain.options.map(o => normalizeOptions(o)),
|
||||
ignore: ignore || undefined,
|
||||
babelrc: babelrc || undefined,
|
||||
ignore: ignoreFile || undefined,
|
||||
babelrc: babelrcFile || undefined,
|
||||
config: configFile || undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function babelrcLoadEnabled(
|
||||
context: ConfigContext,
|
||||
pkgData: FilePackageData,
|
||||
babelrcRoots: BabelrcSearch | void,
|
||||
): 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) {
|
||||
return pkgData.directories.indexOf(absoluteRoot) !== -1;
|
||||
}
|
||||
|
||||
let babelrcPatterns = babelrcRoots;
|
||||
if (!Array.isArray(babelrcPatterns)) babelrcPatterns = [babelrcPatterns];
|
||||
babelrcPatterns = babelrcPatterns.map(pat => path.resolve(context.cwd, pat));
|
||||
|
||||
// Fast path to avoid having to load micromatch if the babelrc is just
|
||||
// loading in the standard root directory.
|
||||
if (babelrcPatterns.length === 1 && babelrcPatterns[0] === absoluteRoot) {
|
||||
return pkgData.directories.indexOf(absoluteRoot) !== -1;
|
||||
}
|
||||
|
||||
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),
|
||||
@@ -189,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),
|
||||
);
|
||||
@@ -284,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 = [];
|
||||
@@ -376,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;
|
||||
@@ -414,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;
|
||||
@@ -496,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`,
|
||||
);
|
||||
@@ -522,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`,
|
||||
);
|
||||
@@ -541,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`,
|
||||
);
|
||||
@@ -616,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', {}],`,
|
||||
|
||||
@@ -5,45 +5,35 @@ import path from "path";
|
||||
import fs from "fs";
|
||||
import json5 from "json5";
|
||||
import resolve from "resolve";
|
||||
import { makeStrongCache, type CacheConfigurator } from "../caching";
|
||||
import {
|
||||
makeStrongCache,
|
||||
makeWeakCache,
|
||||
type CacheConfigurator,
|
||||
} from "../caching";
|
||||
import makeAPI from "../helpers/config-api";
|
||||
import { makeStaticFileCache } from "./utils";
|
||||
import type { FilePackageData, RelativeConfig, ConfigFile } from "./types";
|
||||
|
||||
const debug = buildDebug("babel:config:loading:files:configuration");
|
||||
|
||||
export type ConfigFile = {
|
||||
filepath: string,
|
||||
dirname: string,
|
||||
options: {},
|
||||
};
|
||||
|
||||
export type IgnoreFile = {
|
||||
filepath: string,
|
||||
dirname: string,
|
||||
ignore: Array<string>,
|
||||
};
|
||||
|
||||
export type RelativeConfig = {
|
||||
config: ConfigFile | null,
|
||||
ignore: IgnoreFile | null,
|
||||
};
|
||||
const BABEL_CONFIG_JS_FILENAME = "babel.config.js";
|
||||
|
||||
const BABELRC_FILENAME = ".babelrc";
|
||||
const BABELRC_JS_FILENAME = ".babelrc.js";
|
||||
const PACKAGE_FILENAME = "package.json";
|
||||
const BABELIGNORE_FILENAME = ".babelignore";
|
||||
|
||||
export function findRelativeConfig(
|
||||
filepath: string,
|
||||
packageData: FilePackageData,
|
||||
envName: string,
|
||||
): RelativeConfig {
|
||||
let config = null;
|
||||
let ignore = null;
|
||||
|
||||
const dirname = path.dirname(filepath);
|
||||
let loc = dirname;
|
||||
while (true) {
|
||||
const dirname = path.dirname(packageData.filepath);
|
||||
|
||||
for (const loc of packageData.directories) {
|
||||
if (!config) {
|
||||
config = [BABELRC_FILENAME, BABELRC_JS_FILENAME, PACKAGE_FILENAME].reduce(
|
||||
config = [BABELRC_FILENAME, BABELRC_JS_FILENAME].reduce(
|
||||
(previousConfig: ConfigFile | null, name) => {
|
||||
const filepath = path.join(loc, name);
|
||||
const config = readConfig(filepath, envName);
|
||||
@@ -62,6 +52,23 @@ export function findRelativeConfig(
|
||||
null,
|
||||
);
|
||||
|
||||
const pkgConfig =
|
||||
packageData.pkg && packageData.pkg.dirname === loc
|
||||
? packageToBabelConfig(packageData.pkg)
|
||||
: null;
|
||||
|
||||
if (pkgConfig) {
|
||||
if (config) {
|
||||
throw new Error(
|
||||
`Multiple configuration files found. Please remove one:\n` +
|
||||
` - ${path.basename(pkgConfig.filepath)}#babel\n` +
|
||||
` - ${path.basename(config.filepath)}\n` +
|
||||
`from ${loc}`,
|
||||
);
|
||||
}
|
||||
config = pkgConfig;
|
||||
}
|
||||
|
||||
if (config) {
|
||||
debug("Found configuration %o from %o.", config.filepath, dirname);
|
||||
}
|
||||
@@ -75,15 +82,24 @@ export function findRelativeConfig(
|
||||
debug("Found ignore %o from %o.", ignore.filepath, dirname);
|
||||
}
|
||||
}
|
||||
|
||||
const nextLoc = path.dirname(loc);
|
||||
if (loc === nextLoc) break;
|
||||
loc = nextLoc;
|
||||
}
|
||||
|
||||
return { config, ignore };
|
||||
}
|
||||
|
||||
export function findRootConfig(
|
||||
dirname: string,
|
||||
envName: string,
|
||||
): ConfigFile | null {
|
||||
const filepath = path.resolve(dirname, BABEL_CONFIG_JS_FILENAME);
|
||||
|
||||
const conf = readConfig(filepath, envName);
|
||||
if (conf) {
|
||||
debug("Found root config %o in $o.", BABEL_CONFIG_JS_FILENAME, dirname);
|
||||
}
|
||||
return conf;
|
||||
}
|
||||
|
||||
export function loadConfig(
|
||||
name: string,
|
||||
dirname: string,
|
||||
@@ -107,7 +123,7 @@ export function loadConfig(
|
||||
function readConfig(filepath, envName): ConfigFile | null {
|
||||
return path.extname(filepath) === ".js"
|
||||
? readConfigJS(filepath, { envName })
|
||||
: readConfigFile(filepath);
|
||||
: readConfigJSON5(filepath);
|
||||
}
|
||||
|
||||
const LOADING_CONFIGS = new Set();
|
||||
@@ -180,27 +196,35 @@ const readConfigJS = makeStrongCache(
|
||||
},
|
||||
);
|
||||
|
||||
const readConfigFile = makeStaticFileCache((filepath, content) => {
|
||||
let options;
|
||||
if (path.basename(filepath) === PACKAGE_FILENAME) {
|
||||
try {
|
||||
options = JSON.parse(content).babel;
|
||||
} catch (err) {
|
||||
err.message = `${filepath}: Error while parsing JSON - ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
if (!options) return null;
|
||||
} else {
|
||||
try {
|
||||
options = json5.parse(content);
|
||||
} catch (err) {
|
||||
err.message = `${filepath}: Error while parsing config - ${err.message}`;
|
||||
throw err;
|
||||
const packageToBabelConfig = makeWeakCache(
|
||||
(file: ConfigFile): ConfigFile | null => {
|
||||
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`);
|
||||
}
|
||||
|
||||
if (!options) throw new Error(`${filepath}: No config detected`);
|
||||
return {
|
||||
filepath: file.filepath,
|
||||
dirname: file.dirname,
|
||||
options: babel,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
const readConfigJSON5 = makeStaticFileCache((filepath, content) => {
|
||||
let options;
|
||||
try {
|
||||
options = json5.parse(content);
|
||||
} catch (err) {
|
||||
err.message = `${filepath}: Error while parsing config - ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (!options) throw new Error(`${filepath}: No config detected`);
|
||||
|
||||
if (typeof options !== "object") {
|
||||
throw new Error(`${filepath}: Config returned typeof ${typeof options}`);
|
||||
}
|
||||
@@ -228,27 +252,6 @@ const readIgnoreConfig = makeStaticFileCache((filepath, content) => {
|
||||
};
|
||||
});
|
||||
|
||||
function makeStaticFileCache<T>(fn: (string, string) => T): string => T | null {
|
||||
return makeStrongCache((filepath, cache) => {
|
||||
if (cache.invalidate(() => fileMtime(filepath)) === null) {
|
||||
cache.forever();
|
||||
return null;
|
||||
}
|
||||
|
||||
return fn(filepath, fs.readFileSync(filepath, "utf8"));
|
||||
});
|
||||
}
|
||||
|
||||
function fileMtime(filepath: string): number | null {
|
||||
try {
|
||||
return +fs.statSync(filepath).mtime;
|
||||
} catch (e) {
|
||||
if (e.code !== "ENOENT") throw e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function throwConfigError() {
|
||||
throw new Error(`\
|
||||
Caching was left unconfigured. Babel's plugins, presets, and .babelrc.js files can be configured
|
||||
|
||||
@@ -1,17 +1,42 @@
|
||||
// @flow
|
||||
|
||||
import type { ConfigFile, IgnoreFile, RelativeConfig } from "./configuration";
|
||||
import type {
|
||||
ConfigFile,
|
||||
IgnoreFile,
|
||||
RelativeConfig,
|
||||
FilePackageData,
|
||||
} from "./types";
|
||||
|
||||
export type { ConfigFile, IgnoreFile, RelativeConfig };
|
||||
export type { ConfigFile, IgnoreFile, RelativeConfig, FilePackageData };
|
||||
|
||||
export function findRelativeConfig(
|
||||
filepath: string,
|
||||
envName: string, // eslint-disable-line no-unused-vars
|
||||
): RelativeConfig {
|
||||
return { config: null, ignore: null };
|
||||
export function findPackageData(filepath: string): FilePackageData {
|
||||
return {
|
||||
filepath,
|
||||
directories: [],
|
||||
pkg: null,
|
||||
isPackage: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function loadConfig(name: string, dirname: string): ConfigFile {
|
||||
export function findRelativeConfig(
|
||||
pkgData: FilePackageData,
|
||||
envName: string, // eslint-disable-line no-unused-vars
|
||||
): RelativeConfig {
|
||||
return { pkg: null, config: null, ignore: null };
|
||||
}
|
||||
|
||||
export function findRootConfig(
|
||||
dirname: string,
|
||||
envName: string, // eslint-disable-line no-unused-vars
|
||||
): ConfigFile | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function loadConfig(
|
||||
name: string,
|
||||
dirname: string,
|
||||
envName: string, // eslint-disable-line no-unused-vars
|
||||
): ConfigFile {
|
||||
throw new Error(`Cannot load ${name} relative to ${dirname} in a browser`);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,5 +7,22 @@ import typeof * as indexType from "./index";
|
||||
// exports of index-browser, since this file may be replaced at bundle time with index-browser.
|
||||
((({}: any): $Exact<indexBrowserType>): $Exact<indexType>);
|
||||
|
||||
export * from "./configuration";
|
||||
export * from "./plugins";
|
||||
export { findPackageData } from "./package";
|
||||
|
||||
export {
|
||||
findRelativeConfig,
|
||||
findRootConfig,
|
||||
loadConfig,
|
||||
} from "./configuration";
|
||||
export type {
|
||||
ConfigFile,
|
||||
IgnoreFile,
|
||||
RelativeConfig,
|
||||
FilePackageData,
|
||||
} from "./types";
|
||||
export {
|
||||
resolvePlugin,
|
||||
resolvePreset,
|
||||
loadPlugin,
|
||||
loadPreset,
|
||||
} from "./plugins";
|
||||
|
||||
60
packages/babel-core/src/config/files/package.js
Normal file
60
packages/babel-core/src/config/files/package.js
Normal file
@@ -0,0 +1,60 @@
|
||||
// @flow
|
||||
|
||||
import path from "path";
|
||||
import { makeStaticFileCache } from "./utils";
|
||||
|
||||
import type { ConfigFile, FilePackageData } from "./types";
|
||||
|
||||
const PACKAGE_FILENAME = "package.json";
|
||||
|
||||
/**
|
||||
* Find metadata about the package that this file is inside of. Resolution
|
||||
* of Babel's config requires general package information to decide when to
|
||||
* search for .babelrc files
|
||||
*/
|
||||
export function findPackageData(filepath: string): FilePackageData {
|
||||
let pkg = null;
|
||||
const directories = [];
|
||||
let isPackage = true;
|
||||
|
||||
let dirname = path.dirname(filepath);
|
||||
while (!pkg && path.basename(dirname) !== "node_modules") {
|
||||
directories.push(dirname);
|
||||
|
||||
pkg = readConfigPackage(path.join(dirname, PACKAGE_FILENAME));
|
||||
|
||||
const nextLoc = path.dirname(dirname);
|
||||
if (dirname === nextLoc) {
|
||||
isPackage = false;
|
||||
break;
|
||||
}
|
||||
dirname = nextLoc;
|
||||
}
|
||||
|
||||
return { filepath, directories, pkg, isPackage };
|
||||
}
|
||||
|
||||
const readConfigPackage = makeStaticFileCache(
|
||||
(filepath, content): ConfigFile => {
|
||||
let options;
|
||||
try {
|
||||
options = JSON.parse(content);
|
||||
} catch (err) {
|
||||
err.message = `${filepath}: Error while parsing JSON - ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (typeof options !== "object") {
|
||||
throw new Error(`${filepath}: Config returned typeof ${typeof options}`);
|
||||
}
|
||||
if (Array.isArray(options)) {
|
||||
throw new Error(`${filepath}: Expected config object but found array`);
|
||||
}
|
||||
|
||||
return {
|
||||
filepath,
|
||||
dirname: path.dirname(filepath),
|
||||
options,
|
||||
};
|
||||
},
|
||||
);
|
||||
38
packages/babel-core/src/config/files/types.js
Normal file
38
packages/babel-core/src/config/files/types.js
Normal file
@@ -0,0 +1,38 @@
|
||||
// @flow
|
||||
|
||||
export type ConfigFile = {
|
||||
filepath: string,
|
||||
dirname: string,
|
||||
options: {},
|
||||
};
|
||||
|
||||
export type IgnoreFile = {
|
||||
filepath: string,
|
||||
dirname: string,
|
||||
ignore: Array<string>,
|
||||
};
|
||||
|
||||
export type RelativeConfig = {
|
||||
// The actual config, either from package.json#babel, .babelrc, or
|
||||
// .babelrc.js, if there was one.
|
||||
config: ConfigFile | null,
|
||||
|
||||
// The .babelignore, if there was one.
|
||||
ignore: IgnoreFile | null,
|
||||
};
|
||||
|
||||
export type FilePackageData = {
|
||||
// The file in the package.
|
||||
filepath: string,
|
||||
|
||||
// Any ancestor directories of the file that are within the package.
|
||||
directories: Array<string>,
|
||||
|
||||
// The contents of the package.json. May not be found if the package just
|
||||
// terminated at a node_modules folder without finding one.
|
||||
pkg: ConfigFile | null,
|
||||
|
||||
// True if a package.json or node_modules folder was found while traversing
|
||||
// the directory structure.
|
||||
isPackage: boolean,
|
||||
};
|
||||
27
packages/babel-core/src/config/files/utils.js
Normal file
27
packages/babel-core/src/config/files/utils.js
Normal file
@@ -0,0 +1,27 @@
|
||||
// @flow
|
||||
|
||||
import fs from "fs";
|
||||
import { makeStrongCache } from "../caching";
|
||||
|
||||
export function makeStaticFileCache<T>(
|
||||
fn: (string, string) => T,
|
||||
): string => T | null {
|
||||
return makeStrongCache((filepath, cache) => {
|
||||
if (cache.invalidate(() => fileMtime(filepath)) === null) {
|
||||
cache.forever();
|
||||
return null;
|
||||
}
|
||||
|
||||
return fn(filepath, fs.readFileSync(filepath, "utf8"));
|
||||
});
|
||||
}
|
||||
|
||||
function fileMtime(filepath: string): number | null {
|
||||
try {
|
||||
return +fs.statSync(filepath).mtime;
|
||||
} catch (e) {
|
||||
if (e.code !== "ENOENT" && e.code !== "ENOTDIR") throw e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ export default function loadPrivatePartialConfig(
|
||||
context: ConfigContext,
|
||||
ignore: IgnoreFile | void,
|
||||
babelrc: ConfigFile | void,
|
||||
config: ConfigFile | void,
|
||||
} | null {
|
||||
if (
|
||||
inputOpts != null &&
|
||||
@@ -27,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,
|
||||
};
|
||||
|
||||
@@ -48,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),
|
||||
@@ -64,6 +74,7 @@ export default function loadPrivatePartialConfig(
|
||||
context,
|
||||
ignore: configChain.ignore,
|
||||
babelrc: configChain.babelrc,
|
||||
config: configChain.config,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -71,7 +82,7 @@ export function loadPartialConfig(inputOpts: mixed): PartialConfig | null {
|
||||
const result = loadPrivatePartialConfig(inputOpts);
|
||||
if (!result) return null;
|
||||
|
||||
const { options, babelrc, ignore } = result;
|
||||
const { options, babelrc, ignore, config } = result;
|
||||
|
||||
(options.plugins || []).forEach(item => {
|
||||
if (item.value instanceof Plugin) {
|
||||
@@ -86,6 +97,7 @@ export function loadPartialConfig(inputOpts: mixed): PartialConfig | null {
|
||||
options,
|
||||
babelrc ? babelrc.filepath : undefined,
|
||||
ignore ? ignore.filepath : undefined,
|
||||
config ? config.filepath : undefined,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -99,15 +111,18 @@ class PartialConfig {
|
||||
options: ValidatedOptions;
|
||||
babelrc: string | void;
|
||||
babelignore: string | void;
|
||||
config: string | void;
|
||||
|
||||
constructor(
|
||||
options: ValidatedOptions,
|
||||
babelrc: string | void,
|
||||
ignore: string | void,
|
||||
config: string | void,
|
||||
) {
|
||||
this.options = options;
|
||||
this.babelignore = ignore;
|
||||
this.babelrc = babelrc;
|
||||
this.config = config;
|
||||
|
||||
// Freeze since this is a public API and it should be extremely obvious that
|
||||
// reassigning properties on here does nothing.
|
||||
@@ -122,7 +137,7 @@ class PartialConfig {
|
||||
* this.babelrc directly.
|
||||
*/
|
||||
hasFilesystemConfig(): boolean {
|
||||
return this.babelrc !== undefined;
|
||||
return this.babelrc !== undefined || this.config !== undefined;
|
||||
}
|
||||
}
|
||||
Object.freeze(PartialConfig.prototype);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
|
||||
import type {
|
||||
ConfigFileSearch,
|
||||
BabelrcSearch,
|
||||
IgnoreList,
|
||||
IgnoreItem,
|
||||
PluginList,
|
||||
@@ -164,6 +166,45 @@ function checkValidTest(value: mixed): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
export function assertConfigFileSearch(
|
||||
key: string,
|
||||
value: mixed,
|
||||
): ConfigFileSearch | void {
|
||||
if (
|
||||
value !== undefined &&
|
||||
typeof value !== "boolean" &&
|
||||
typeof value !== "string"
|
||||
) {
|
||||
throw new Error(
|
||||
`.${key} must be a undefined, a boolean, a string, ` +
|
||||
`got ${JSON.stringify(value)}`,
|
||||
);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertBabelrcSearch(
|
||||
key: string,
|
||||
value: mixed,
|
||||
): BabelrcSearch | void {
|
||||
if (value === undefined || typeof value === "boolean") return value;
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach((item, i) => {
|
||||
if (typeof item !== "string") {
|
||||
throw new Error(`.${key}[${i}] must be a string.`);
|
||||
}
|
||||
});
|
||||
} else if (typeof value !== "string") {
|
||||
throw new Error(
|
||||
`.${key} must be a undefined, a boolean, a string, ` +
|
||||
`or an array of strings, got ${JSON.stringify(value)}`,
|
||||
);
|
||||
}
|
||||
return (value: any);
|
||||
}
|
||||
|
||||
export function assertPluginList(key: string, value: mixed): PluginList | void {
|
||||
const arr = assertArray(key, value);
|
||||
if (arr) {
|
||||
|
||||
@@ -13,6 +13,8 @@ import {
|
||||
assertIgnoreList,
|
||||
assertPluginList,
|
||||
assertConfigApplicableTest,
|
||||
assertConfigFileSearch,
|
||||
assertBabelrcSearch,
|
||||
assertFunction,
|
||||
assertSourceMaps,
|
||||
assertCompact,
|
||||
@@ -23,15 +25,17 @@ import {
|
||||
|
||||
const ROOT_VALIDATORS: ValidatorSet = {
|
||||
cwd: (assertString: Validator<$PropertyType<ValidatedOptions, "cwd">>),
|
||||
root: (assertString: Validator<$PropertyType<ValidatedOptions, "root">>),
|
||||
configFile: (assertConfigFileSearch: Validator<
|
||||
$PropertyType<ValidatedOptions, "configFile">,
|
||||
>),
|
||||
|
||||
filename: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "filename">,
|
||||
>),
|
||||
filenameRelative: (assertString: Validator<
|
||||
$PropertyType<ValidatedOptions, "filenameRelative">,
|
||||
>),
|
||||
babelrc: (assertBoolean: Validator<
|
||||
$PropertyType<ValidatedOptions, "babelrc">,
|
||||
>),
|
||||
code: (assertBoolean: Validator<$PropertyType<ValidatedOptions, "code">>),
|
||||
ast: (assertBoolean: Validator<$PropertyType<ValidatedOptions, "ast">>),
|
||||
|
||||
@@ -40,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 = {
|
||||
@@ -83,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">,
|
||||
>),
|
||||
@@ -151,6 +166,9 @@ export type ValidatedOptions = {
|
||||
filename?: string,
|
||||
filenameRelative?: string,
|
||||
babelrc?: boolean,
|
||||
babelrcRoots?: BabelrcSearch,
|
||||
configFile?: ConfigFileSearch,
|
||||
root?: string,
|
||||
code?: boolean,
|
||||
ast?: boolean,
|
||||
inputSourceMap?: RootInputSourceMapOption,
|
||||
@@ -223,12 +241,21 @@ export type PluginList = $ReadOnlyArray<PluginItem>;
|
||||
export type OverridesList = Array<ValidatedOptions>;
|
||||
export type ConfigApplicableTest = IgnoreItem | Array<IgnoreItem>;
|
||||
|
||||
export type ConfigFileSearch = string | boolean;
|
||||
export type BabelrcSearch = boolean | string | Array<string>;
|
||||
export type SourceMapsOption = boolean | "inline" | "both";
|
||||
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);
|
||||
@@ -240,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`);
|
||||
}
|
||||
@@ -253,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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ export default function loadBlockHoistPlugin(): Plugin {
|
||||
// which loads this file, and this 'loadConfig' loading plugins.
|
||||
const config = loadConfig({
|
||||
babelrc: false,
|
||||
configFile: false,
|
||||
plugins: [blockHoistPlugin],
|
||||
});
|
||||
LOADED_PLUGIN = config ? config.passes[0][0] : undefined;
|
||||
|
||||
@@ -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,8 @@ 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,
|
||||
"fixtures",
|
||||
@@ -346,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"); } }',
|
||||
@@ -393,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,
|
||||
@@ -544,7 +632,7 @@ describe("api", function() {
|
||||
});
|
||||
|
||||
it("default", function() {
|
||||
const result = babel.transform("foo;", {
|
||||
const result = transform("foo;", {
|
||||
env: {
|
||||
development: { comments: false },
|
||||
},
|
||||
@@ -555,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 },
|
||||
},
|
||||
@@ -565,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 },
|
||||
},
|
||||
@@ -623,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) {
|
||||
@@ -640,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,16 +1,24 @@
|
||||
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", () => {
|
||||
it("should process matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: fixture("nonexistant-fake"),
|
||||
@@ -22,6 +30,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: new RegExp(fixture("nonexistant-fake")),
|
||||
@@ -33,6 +42,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: p => p.indexOf(fixture("nonexistant-fake")) === 0,
|
||||
@@ -44,6 +54,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: fixture("nonexistant-fake-unknown"),
|
||||
@@ -55,6 +66,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: new RegExp(fixture("nonexistant-unknown")),
|
||||
@@ -66,6 +78,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: p => p.indexOf(fixture("nonexistant-unknown")) === 0,
|
||||
@@ -79,6 +92,7 @@ describe("buildConfigChain", function() {
|
||||
describe("array", () => {
|
||||
it("should process matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: [fixture("nonexistant-fake")],
|
||||
@@ -90,6 +104,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: [new RegExp(fixture("nonexistant-fake"))],
|
||||
@@ -101,6 +116,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: [p => p.indexOf(fixture("nonexistant-fake")) === 0],
|
||||
@@ -112,6 +128,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: [fixture("nonexistant-fake-unknown")],
|
||||
@@ -123,6 +140,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: [new RegExp(fixture("nonexistant-unknown"))],
|
||||
@@ -134,6 +152,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
test: [p => p.indexOf(fixture("nonexistant-unknown")) === 0],
|
||||
@@ -149,6 +168,7 @@ describe("buildConfigChain", function() {
|
||||
describe("single", () => {
|
||||
it("should process matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: fixture("nonexistant-fake"),
|
||||
@@ -160,6 +180,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: new RegExp(fixture("nonexistant-fake")),
|
||||
@@ -171,6 +192,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: p => p.indexOf(fixture("nonexistant-fake")) === 0,
|
||||
@@ -182,6 +204,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: fixture("nonexistant-fake-unknown"),
|
||||
@@ -193,6 +216,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: new RegExp(fixture("nonexistant-unknown")),
|
||||
@@ -204,6 +228,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: p => p.indexOf(fixture("nonexistant-unknown")) === 0,
|
||||
@@ -217,6 +242,7 @@ describe("buildConfigChain", function() {
|
||||
describe("array", () => {
|
||||
it("should process matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: [fixture("nonexistant-fake")],
|
||||
@@ -228,6 +254,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: [new RegExp(fixture("nonexistant-fake"))],
|
||||
@@ -239,6 +266,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: [p => p.indexOf(fixture("nonexistant-fake")) === 0],
|
||||
@@ -250,6 +278,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: [fixture("nonexistant-fake-unknown")],
|
||||
@@ -261,6 +290,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: [new RegExp(fixture("nonexistant-unknown"))],
|
||||
@@ -272,6 +302,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
include: [p => p.indexOf(fixture("nonexistant-unknown")) === 0],
|
||||
@@ -287,6 +318,7 @@ describe("buildConfigChain", function() {
|
||||
describe("single", () => {
|
||||
it("should process matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: fixture("nonexistant-fake"),
|
||||
@@ -298,6 +330,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: new RegExp(fixture("nonexistant-fake")),
|
||||
@@ -309,6 +342,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: p => p.indexOf(fixture("nonexistant-fake")) === 0,
|
||||
@@ -320,6 +354,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: fixture("nonexistant-fake-unknown"),
|
||||
@@ -331,6 +366,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: new RegExp(fixture("nonexistant-unknown")),
|
||||
@@ -342,6 +378,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: p => p.indexOf(fixture("nonexistant-unknown")) === 0,
|
||||
@@ -355,6 +392,7 @@ describe("buildConfigChain", function() {
|
||||
describe("array", () => {
|
||||
it("should process matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: [fixture("nonexistant-fake")],
|
||||
@@ -366,6 +404,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: [new RegExp(fixture("nonexistant-fake"))],
|
||||
@@ -377,6 +416,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: [p => p.indexOf(fixture("nonexistant-fake")) === 0],
|
||||
@@ -388,6 +428,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching string values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: [fixture("nonexistant-fake-unknown")],
|
||||
@@ -399,6 +440,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching RegExp values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: [new RegExp(fixture("nonexistant-unknown"))],
|
||||
@@ -410,6 +452,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should process non-matching function values", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
exclude: [p => p.indexOf(fixture("nonexistant-unknown")) === 0],
|
||||
@@ -424,6 +467,7 @@ describe("buildConfigChain", function() {
|
||||
describe("ignore", () => {
|
||||
it("should ignore files that match", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [
|
||||
@@ -441,6 +485,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should not ignore files that don't match", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [
|
||||
@@ -456,6 +501,7 @@ describe("buildConfigChain", function() {
|
||||
describe("only", () => {
|
||||
it("should ignore files that don't match", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
only: [
|
||||
@@ -469,6 +515,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should not ignore files that match", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
only: [
|
||||
@@ -484,6 +531,7 @@ describe("buildConfigChain", function() {
|
||||
describe("ignore/only", () => {
|
||||
it("should ignore files that match ignore and don't match only", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [fixture("nonexistant-fake", "src.js")],
|
||||
@@ -495,6 +543,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should ignore files that match ignore and also only", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [fixture("nonexistant-fake", "src.js")],
|
||||
@@ -506,6 +555,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should not ignore files that match only and not ignore", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
only: [fixture("nonexistant-fake", "src.js")],
|
||||
@@ -516,6 +566,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should not ignore files when no ignore/only are specified", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
});
|
||||
@@ -525,6 +576,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should allow negation of only", () => {
|
||||
const opts1 = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
only: [
|
||||
@@ -535,6 +587,7 @@ describe("buildConfigChain", function() {
|
||||
expect(opts1).toBeNull();
|
||||
|
||||
const opts2 = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
only: [
|
||||
@@ -545,6 +598,7 @@ describe("buildConfigChain", function() {
|
||||
expect(opts2).not.toBeNull();
|
||||
|
||||
const opts3 = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "folder", "src.js"),
|
||||
babelrc: false,
|
||||
only: [
|
||||
@@ -557,6 +611,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should allow negation of ignore", () => {
|
||||
const opts1 = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
ignore: [
|
||||
@@ -568,6 +623,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
// Tests disabled pending https://github.com/babel/babel/issues/6907
|
||||
// const opts2 = loadOptions({
|
||||
// cwd: fixture("nonexistant-fake"),
|
||||
// filename: fixture("nonexistant-fake", "src.js"),
|
||||
// babelrc: false,
|
||||
// ignore: [
|
||||
@@ -575,9 +631,10 @@ describe("buildConfigChain", function() {
|
||||
// fixture("nonexistant-fake"),
|
||||
// ],
|
||||
// });
|
||||
// assert.notEqual(opts2, null);
|
||||
// expect(opts2).not.toBeNull();
|
||||
//
|
||||
// const opts3 = loadOptions({
|
||||
// cwd: fixture("nonexistant-fake"),
|
||||
// filename: fixture("nonexistant-fake", "folder", "src.js"),
|
||||
// babelrc: false,
|
||||
// ignore: [
|
||||
@@ -585,7 +642,7 @@ describe("buildConfigChain", function() {
|
||||
// fixture("nonexistant-fake"),
|
||||
// ],
|
||||
// });
|
||||
// assert.notEqual(opts3, null);
|
||||
// expect(opts3).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -718,13 +775,13 @@ describe("buildConfigChain", function() {
|
||||
"package.json",
|
||||
);
|
||||
|
||||
const opts1 = loadOptions({ filename });
|
||||
const opts2 = loadOptions({ filename });
|
||||
const opts1 = loadOptions({ filename, cwd: path.dirname(filename) });
|
||||
const opts2 = loadOptions({ filename, cwd: path.dirname(filename) });
|
||||
|
||||
touch(pkgJSON);
|
||||
|
||||
const opts3 = loadOptions({ filename });
|
||||
const opts4 = loadOptions({ filename });
|
||||
const opts3 = loadOptions({ filename, cwd: path.dirname(filename) });
|
||||
const opts4 = loadOptions({ filename, cwd: path.dirname(filename) });
|
||||
|
||||
expect(opts1.plugins).toHaveLength(1);
|
||||
expect(opts2.plugins).toHaveLength(1);
|
||||
@@ -752,13 +809,13 @@ describe("buildConfigChain", function() {
|
||||
".babelrc",
|
||||
);
|
||||
|
||||
const opts1 = loadOptions({ filename });
|
||||
const opts2 = loadOptions({ filename });
|
||||
const opts1 = loadOptions({ filename, cwd: path.dirname(filename) });
|
||||
const opts2 = loadOptions({ filename, cwd: path.dirname(filename) });
|
||||
|
||||
touch(babelrcFile);
|
||||
|
||||
const opts3 = loadOptions({ filename });
|
||||
const opts4 = loadOptions({ filename });
|
||||
const opts3 = loadOptions({ filename, cwd: path.dirname(filename) });
|
||||
const opts4 = loadOptions({ filename, cwd: path.dirname(filename) });
|
||||
|
||||
expect(opts1.plugins).toHaveLength(1);
|
||||
expect(opts2.plugins).toHaveLength(1);
|
||||
@@ -780,11 +837,19 @@ describe("buildConfigChain", function() {
|
||||
"src.js",
|
||||
);
|
||||
|
||||
const opts1 = loadOptions({ filename });
|
||||
const opts2 = loadOptions({ filename });
|
||||
const opts1 = loadOptions({ filename, cwd: path.dirname(filename) });
|
||||
const opts2 = loadOptions({ filename, cwd: path.dirname(filename) });
|
||||
|
||||
const opts3 = loadOptions({ filename, envName: "new-env" });
|
||||
const opts4 = loadOptions({ filename, envName: "new-env" });
|
||||
const opts3 = loadOptions({
|
||||
filename,
|
||||
envName: "new-env",
|
||||
cwd: path.dirname(filename),
|
||||
});
|
||||
const opts4 = loadOptions({
|
||||
filename,
|
||||
envName: "new-env",
|
||||
cwd: path.dirname(filename),
|
||||
});
|
||||
|
||||
expect(opts1.plugins).toHaveLength(1);
|
||||
expect(opts2.plugins).toHaveLength(1);
|
||||
@@ -803,6 +868,7 @@ describe("buildConfigChain", function() {
|
||||
describe("overrides merging", () => {
|
||||
it("should apply matching overrides over base configs", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
comments: true,
|
||||
@@ -819,6 +885,7 @@ describe("buildConfigChain", function() {
|
||||
|
||||
it("should not apply non-matching overrides over base configs", () => {
|
||||
const opts = loadOptions({
|
||||
cwd: fixture("nonexistant-fake"),
|
||||
filename: fixture("nonexistant-fake", "src.js"),
|
||||
babelrc: false,
|
||||
comments: true,
|
||||
@@ -837,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: [],
|
||||
@@ -860,9 +929,16 @@ describe("buildConfigChain", function() {
|
||||
it("should load .babelrc", () => {
|
||||
const filename = fixture("config-files", "babelrc", "src.js");
|
||||
|
||||
expect(loadOptions({ filename })).toEqual({
|
||||
expect(
|
||||
loadOptions({
|
||||
filename,
|
||||
cwd: path.dirname(filename),
|
||||
}),
|
||||
).toEqual({
|
||||
...getDefaults(),
|
||||
filename,
|
||||
filename: filename,
|
||||
cwd: path.dirname(filename),
|
||||
root: path.dirname(filename),
|
||||
comments: true,
|
||||
});
|
||||
});
|
||||
@@ -870,9 +946,11 @@ describe("buildConfigChain", function() {
|
||||
it("should load .babelrc.js", () => {
|
||||
const filename = fixture("config-files", "babelrc-js", "src.js");
|
||||
|
||||
expect(loadOptions({ filename })).toEqual({
|
||||
expect(loadOptions({ filename, cwd: path.dirname(filename) })).toEqual({
|
||||
...getDefaults(),
|
||||
filename,
|
||||
filename: filename,
|
||||
cwd: path.dirname(filename),
|
||||
root: path.dirname(filename),
|
||||
comments: true,
|
||||
});
|
||||
});
|
||||
@@ -880,9 +958,11 @@ describe("buildConfigChain", function() {
|
||||
it("should load package.json#babel", () => {
|
||||
const filename = fixture("config-files", "pkg", "src.js");
|
||||
|
||||
expect(loadOptions({ filename })).toEqual({
|
||||
expect(loadOptions({ filename, cwd: path.dirname(filename) })).toEqual({
|
||||
...getDefaults(),
|
||||
filename,
|
||||
filename: filename,
|
||||
cwd: path.dirname(filename),
|
||||
root: path.dirname(filename),
|
||||
comments: true,
|
||||
});
|
||||
});
|
||||
@@ -890,39 +970,41 @@ describe("buildConfigChain", function() {
|
||||
it("should load .babelignore", () => {
|
||||
const filename = fixture("config-files", "babelignore", "src.js");
|
||||
|
||||
expect(loadOptions({ filename })).toBeNull();
|
||||
expect(loadOptions({ filename, cwd: path.dirname(filename) })).toBeNull();
|
||||
});
|
||||
|
||||
it("should throw if there are both .babelrc and .babelrc.js", () => {
|
||||
const filename = fixture("config-files", "both-babelrc", "src.js");
|
||||
|
||||
expect(() => loadOptions({ filename })).toThrow(
|
||||
/Multiple configuration files found/,
|
||||
);
|
||||
expect(() =>
|
||||
loadOptions({ filename, cwd: path.dirname(filename) }),
|
||||
).toThrow(/Multiple configuration files found/);
|
||||
});
|
||||
|
||||
it("should throw if there are both .babelrc and package.json", () => {
|
||||
const filename = fixture("config-files", "pkg-babelrc", "src.js");
|
||||
|
||||
expect(() => loadOptions({ filename })).toThrow(
|
||||
/Multiple configuration files found/,
|
||||
);
|
||||
expect(() =>
|
||||
loadOptions({ filename, cwd: path.dirname(filename) }),
|
||||
).toThrow(/Multiple configuration files found/);
|
||||
});
|
||||
|
||||
it("should throw if there are both .babelrc.js and package.json", () => {
|
||||
const filename = fixture("config-files", "pkg-babelrc-js", "src.js");
|
||||
|
||||
expect(() => loadOptions({ filename })).toThrow(
|
||||
/Multiple configuration files found/,
|
||||
);
|
||||
expect(() =>
|
||||
loadOptions({ filename, cwd: path.dirname(filename) }),
|
||||
).toThrow(/Multiple configuration files found/);
|
||||
});
|
||||
|
||||
it("should ignore package.json without a 'babel' property", () => {
|
||||
const filename = fixture("config-files", "pkg-ignored", "src.js");
|
||||
|
||||
expect(loadOptions({ filename })).toEqual({
|
||||
expect(loadOptions({ filename, cwd: path.dirname(filename) })).toEqual({
|
||||
...getDefaults(),
|
||||
filename,
|
||||
filename: filename,
|
||||
cwd: path.dirname(filename),
|
||||
root: path.dirname(filename),
|
||||
comments: true,
|
||||
});
|
||||
});
|
||||
@@ -930,23 +1012,25 @@ describe("buildConfigChain", function() {
|
||||
it("should show helpful errors for .babelrc", () => {
|
||||
const filename = fixture("config-files", "babelrc-error", "src.js");
|
||||
|
||||
expect(() => loadOptions({ filename })).toThrow(
|
||||
/Error while parsing config - /,
|
||||
);
|
||||
expect(() =>
|
||||
loadOptions({ filename, cwd: path.dirname(filename) }),
|
||||
).toThrow(/Error while parsing config - /);
|
||||
});
|
||||
|
||||
it("should show helpful errors for .babelrc.js", () => {
|
||||
const filename = fixture("config-files", "babelrc-js-error", "src.js");
|
||||
|
||||
expect(() => loadOptions({ filename })).toThrow(/Babelrc threw an error/);
|
||||
expect(() =>
|
||||
loadOptions({ filename, cwd: path.dirname(filename) }),
|
||||
).toThrow(/Babelrc threw an error/);
|
||||
});
|
||||
|
||||
it("should show helpful errors for package.json", () => {
|
||||
const filename = fixture("config-files", "pkg-error", "src.js");
|
||||
|
||||
expect(() => loadOptions({ filename })).toThrow(
|
||||
/Error while parsing JSON - /,
|
||||
);
|
||||
expect(() =>
|
||||
loadOptions({ filename, cwd: path.dirname(filename) }),
|
||||
).toThrow(/Error while parsing JSON - /);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,6 +25,7 @@ describe("@babel/core config loading", () => {
|
||||
|
||||
function makeOpts(skipProgrammatic = false) {
|
||||
return {
|
||||
cwd: path.dirname(FILEPATH),
|
||||
filename: FILEPATH,
|
||||
presets: skipProgrammatic
|
||||
? null
|
||||
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
class A {
|
||||
prop1 = () => this;
|
||||
static prop2 = () => this;
|
||||
prop3 = () => arguments;
|
||||
static prop4 = () => arguments;
|
||||
prop5 = this;
|
||||
static prop6 = this;
|
||||
prop7 = arguments;
|
||||
static prop8 = arguments;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user