Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 13 additions & 34 deletions packages/babel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@ Using Rollup with `@rollup/plugin-babel` makes the process far easier.

## Requirements

This plugin requires an [LTS](https://github.com/nodejs/Release) Node version (v14.0.0+) and Rollup v1.20.0+.
This plugin requires Node.js `^22.18.0 || >=24.11.0` (the range supported by Babel 8), Rollup v4.0.0+ and `@babel/core` v8.0.0+. If you are on Babel 7, use `@rollup/plugin-babel` v7.

This package is published as ES modules only. `require('@rollup/plugin-babel')` keeps working on the supported Node versions via [`require(esm)`](https://nodejs.org/api/modules.html#loading-ecmascript-modules-using-require).

## Migration to v8

- Babel 7 is no longer supported, see the [Babel 8 migration guide](https://babeljs.io/docs/v8-migration) for upgrading your Babel configuration.
- The `runtimeHelpers` and `externalHelpers` plugin options (deprecated since v5 in favour of `babelHelpers`) have been removed.
- The `@types/babel__core` optional peer dependency is gone; Babel 8 ships its own TypeScript types.

## Install

Expand Down Expand Up @@ -110,7 +118,7 @@ const filter = createFilter(include, exclude, {});
### `extensions`

Type: `Array[...String]`<br>
Default: `['.js', '.jsx', '.es6', '.es', '.mjs']`
Default: `['.js', '.jsx', '.es6', '.es', '.mjs', '.cjs']`

An array of file extensions that Babel should transpile. If you want to transpile TypeScript files with this plugin it's essential to include `.ts` and `.tsx` in this option.

Expand Down Expand Up @@ -291,15 +299,15 @@ By default, helpers e.g. when transpiling classes will be inserted at the top of

Alternatively, you can use imported runtime helpers by adding the `@babel/transform-runtime` plugin. This will make `@babel/runtime` an external dependency of your project, see [@babel/plugin-transform-runtime](https://babeljs.io/docs/en/babel-plugin-transform-runtime) for details.

Note that this will only work for `es` and `cjs` formats, and you need to make sure to set the `useESModules` option of `@babel/plugin-transform-runtime` to `true` if you create ES output:
Note that this will only work for `es` and `cjs` formats. Helpers are always imported as `@babel/runtime/helpers/<name>`; whether the ESM or CommonJS flavour is used is resolved from `@babel/runtime`'s `package.json#exports`:

```js
rollup.rollup({...})
.then(bundle => bundle.generate({
format: 'es',
plugins: [getBabelOutputPlugin({
presets: ['@babel/preset-env'],
plugins: [['@babel/plugin-transform-runtime', { useESModules: true }]]
plugins: ['@babel/plugin-transform-runtime']
})]
}))
```
Expand All @@ -309,7 +317,7 @@ rollup.rollup({...})
export default class Foo {}

// output
import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';
import _classCallCheck from '@babel/runtime/helpers/classCallCheck';

var Foo = function Foo() {
_classCallCheck(this, Foo);
Expand All @@ -318,35 +326,6 @@ var Foo = function Foo() {
export default Foo;
```

And for CommonJS:

```js
rollup.rollup({...})
.then(bundle => bundle.generate({
format: 'cjs',
plugins: [getBabelOutputPlugin({
presets: ['@babel/preset-env'],
plugins: [['@babel/plugin-transform-runtime', { useESModules: false }]]
})]
}))
```

```js
// input
export default class Foo {}

// output
('use strict');

var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');

var Foo = function Foo() {
_classCallCheck(this, Foo);
};

module.exports = Foo;
```

Another option is to use `@babel/plugin-external-helpers`, which will reference the global `babelHelpers` object. It is your responsibility to make sure this global variable exists.

## Custom plugin builder
Expand Down
46 changes: 16 additions & 30 deletions packages/babel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,25 @@
"author": "Rich Harris",
"homepage": "https://github.com/rollup/plugins/tree/master/packages/babel#readme",
"bugs": "https://github.com/rollup/plugins/issues",
"main": "./dist/cjs/index.js",
"module": "./dist/es/index.js",
"type": "module",
"exports": {
"types": "./types/index.d.ts",
"import": "./dist/es/index.js",
"default": "./dist/cjs/index.js"
"default": "./src/index.js"
},
"engines": {
"node": ">=14.0.0"
"node": "^22.18.0 || >=24.11.0"
},
"scripts": {
"build": "rollup -c",
"ci:coverage": "nyc pnpm test && nyc report --reporter=text-lcov > coverage.lcov",
"ci:lint": "pnpm build && pnpm lint",
"ci:lint": "pnpm lint",
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}",
"ci:test": "pnpm test -- --reporter=verbose",
"prebuild": "del-cli dist",
"prepare": "if [ ! -d 'dist' ]; then pnpm build; fi",
"prerelease": "pnpm build",
"pretest": "pnpm build",
"release": "pnpm --workspace-root package:release $(pwd)",
"test": "vitest --config ../../.config/vitest.config.mts run",
"test:ts": "tsc types/index.d.ts test/types.ts --noEmit"
"test": "node ./scripts/run-tests-if-supported.mjs",
"test:ts": "tsc types/index.d.ts test/types.ts --noEmit --esModuleInterop"
},
"files": [
"dist",
"!dist/**/*.map",
"src",
"types",
"README.md",
"LICENSE"
Expand All @@ -53,34 +45,28 @@
"es6"
],
"peerDependencies": {
"@babel/core": "^7.0.0",
"@types/babel__core": "^7.1.9",
"rollup": "^2.0.0||^3.0.0||^4.0.0"
"@babel/core": "^8.0.0",
"rollup": ">=4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
},
"@types/babel__core": {
"optional": true
}
},
"dependencies": {
"@babel/helper-module-imports": "^7.18.6",
"@babel/helper-module-imports": "^8.0.0",
"@rollup/pluginutils": "^5.0.1",
"workerpool": "^9.0.0"
},
"devDependencies": {
"@babel/core": "^7.19.1",
"@babel/plugin-external-helpers": "^7.18.6",
"@babel/plugin-proposal-decorators": "^7.19.1",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.19.1",
"@babel/preset-env": "^7.19.1",
"@babel/core": "^8.0.1",
"@babel/plugin-external-helpers": "^8.0.1",
"@babel/plugin-proposal-decorators": "^8.0.2",
"@babel/plugin-transform-runtime": "^8.0.1",
"@babel/preset-env": "^8.0.2",
"@rollup/plugin-json": "^5.0.0",
"@rollup/plugin-node-resolve": "^15.0.0",
"@types/babel__core": "^7.1.9",
"rollup": "^4.0.0-24",
"rollup": "^4.0.0",
"source-map": "^0.7.4"
},
"types": "./types/index.d.ts",
Expand Down
41 changes: 0 additions & 41 deletions packages/babel/rollup.config.mjs

This file was deleted.

22 changes: 22 additions & 0 deletions packages/babel/scripts/run-tests-if-supported.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env node
// Babel 8 requires Node ^22.18.0 || >=24.11.0, but the repo-wide CI matrix also
// runs older Node versions. Skip this package's tests there instead of failing.
import { spawn } from 'node:child_process';

const [major, minor] = process.versions.node.split('.').map(Number);
const supported = (major === 22 && minor >= 18) || (major === 24 && minor >= 11) || major >= 25;

if (!supported) {
// eslint-disable-next-line no-console
console.log(
`skipping tests: Babel 8 requires Node ^22.18.0 || >=24.11.0 (running ${process.versions.node})`
);
process.exit(0);
}

const child = spawn(
'vitest',
['--config', '../../.config/vitest.config.mts', 'run', ...process.argv.slice(2)],
{ stdio: 'inherit', shell: process.platform === 'win32' }
);
child.on('exit', (code) => process.exit(code ?? 1));
35 changes: 13 additions & 22 deletions packages/babel/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,8 @@ const unpackOptions = ({
};
};

const warnAboutDeprecatedHelpersOption = ({ deprecatedOption, suggestion }) => {
// eslint-disable-next-line no-console
console.warn(
`\`${deprecatedOption}\` has been removed in favor a \`babelHelpers\` option. Try changing your configuration to \`${suggestion}\`. ` +
`Refer to the documentation to learn more: https://github.com/rollup/plugins/tree/master/packages/babel#babelhelpers`
);
};

const unpackInputPluginOptions = ({ skipPreflightCheck = false, ...rest }) => {
if ('runtimeHelpers' in rest) {
warnAboutDeprecatedHelpersOption({
deprecatedOption: 'runtimeHelpers',
suggestion: `babelHelpers: 'runtime'`
});
} else if ('externalHelpers' in rest) {
warnAboutDeprecatedHelpersOption({
deprecatedOption: 'externalHelpers',
suggestion: `babelHelpers: 'external'`
});
} else if (!rest.babelHelpers) {
if (!rest.babelHelpers) {
// eslint-disable-next-line no-console
console.warn(
"babelHelpers: 'bundled' option was used by default. It is recommended to configure this option explicitly, read more here: " +
Expand Down Expand Up @@ -330,11 +312,8 @@ function createBabelOutputPluginFactory(customCallback = returnObject) {
excludeChunks,
exclude,
extensions,
externalHelpers,
externalHelpersWhitelist,
include,
parallel,
runtimeHelpers,
...babelOptions
} = unpackOutputPluginOptions(pluginOptionsWithOverrides, outputOptions);
/* eslint-enable no-unused-vars */
Expand Down Expand Up @@ -392,3 +371,15 @@ export { createBabelInputPluginFactory, createBabelOutputPluginFactory };
export default getBabelInputPlugin;
// support `rollup -c —plugin babel`
export { getBabelInputPlugin as babel };

// make `require('@rollup/plugin-babel')` return the callable default export with
// the named exports attached, like the removed CJS build did
const cjsExports = Object.assign(getBabelInputPlugin, {
default: getBabelInputPlugin,
babel: getBabelInputPlugin,
getBabelInputPlugin,
getBabelOutputPlugin,
createBabelInputPluginFactory,
createBabelOutputPluginFactory
});
export { cjsExports as 'module.exports' };
3 changes: 0 additions & 3 deletions packages/babel/src/package.json

This file was deleted.

3 changes: 1 addition & 2 deletions packages/babel/src/preflightCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ function helpersTestTransform() {
const mismatchError = (actual, expected, filename) =>
`You have declared using "${expected}" babelHelpers, but transforming ${filename} resulted in "${actual}". Please check your configuration.`;

// Revert to /\/helpers\/(esm\/)?inherits/ when Babel 8 gets released, this was fixed in https://github.com/babel/babel/issues/14185
const inheritsHelperRe = /[\\/]+helpers[\\/]+(esm[\\/]+)?inherits/;
const inheritsHelperRe = /\/helpers\/(esm\/)?inherits/;

export default async function preflightCheck(error, babelHelpers, transformOptions) {
const finalOptions = addBabelPlugin(transformOptions, helpersTestTransform);
Expand Down
3 changes: 1 addition & 2 deletions packages/babel/src/transformCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ export default async function transformCode({
skipPreflightCheck,
babelHelpers
}) {
// loadPartialConfigAsync has become available in @babel/core@7.8.0
const config = await (babel.loadPartialConfigAsync || babel.loadPartialConfig)(babelOptions);
const config = await babel.loadPartialConfigAsync(babelOptions);

// file is ignored by babel
if (!config) {
Expand Down
19 changes: 10 additions & 9 deletions packages/babel/test/as-input-plugin.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ test('generates sourcemap by default', async () => {
source: 'test/fixtures/class/main.js'.split(nodePath.sep).join('/'),
line: 3,
column: 12,
name: target
// Babel 8 no longer records a name mapping for identifiers whose text is unchanged
name: null
});
});
test('works with proposal-decorators (rollup/rollup-plugin-babel#18)', async () => {
Expand Down Expand Up @@ -273,7 +274,7 @@ var Foo = /*#__PURE__*/_createClass(function Foo() {
module.exports = Foo;
`);
});
test('allows transform-runtime to inject esm version of helpers', async () => {
test('allows transform-runtime to inject helpers in esm output', async () => {
const warnings = [];
const code = await generate(
'runtime-helpers-esm/main.js',
Expand All @@ -290,11 +291,11 @@ test('allows transform-runtime to inject esm version of helpers', async () => {
}
);
expect(warnings).toEqual([
`"@babel/runtime/helpers/esm/createClass" is imported by "test/fixtures/runtime-helpers-esm/main.js", but could not be resolved – treating it as an external dependency.`,
`"@babel/runtime/helpers/esm/classCallCheck" is imported by "test/fixtures/runtime-helpers-esm/main.js", but could not be resolved – treating it as an external dependency.`
`"@babel/runtime/helpers/createClass" is imported by "test/fixtures/runtime-helpers-esm/main.js", but could not be resolved – treating it as an external dependency.`,
`"@babel/runtime/helpers/classCallCheck" is imported by "test/fixtures/runtime-helpers-esm/main.js", but could not be resolved – treating it as an external dependency.`
]);
expect(code).toBe(`import _createClass from '@babel/runtime/helpers/esm/createClass';
import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';
expect(code).toBe(`import _createClass from '@babel/runtime/helpers/createClass';
import _classCallCheck from '@babel/runtime/helpers/classCallCheck';

var Foo = /*#__PURE__*/_createClass(function Foo() {
_classCallCheck(this, Foo);
Expand Down Expand Up @@ -573,7 +574,7 @@ test('can be used as an input plugin while transforming the output', async () =>
input: `${FIXTURES}basic/main.js`,
plugins: [
getBabelOutputPlugin({
presets: ['@babel/env']
presets: [['@babel/env', { targets: { ie: '11' } }]]
})
]
});
Expand All @@ -587,7 +588,7 @@ test('works as a CJS plugin', async () => {
input: `${FIXTURES}basic/main.js`,
plugins: [
babelPluginCjs({
presets: ['@babel/env']
presets: [['@babel/env', { targets: { ie: '11' } }]]
})
]
});
Expand All @@ -603,7 +604,7 @@ test('works in parallel as a CJS plugin', async () => {
plugins: [
babelPluginCjs({
babelHelpers: 'bundled',
presets: ['@babel/env'],
presets: [['@babel/env', { targets: { ie: '11' } }]],
parallel: true
})
]
Expand Down
Loading