diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a7bebb1..87b03e25 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - node-version: [10.x, 12.x, 14.x] + node-version: [10.x, 12.x, 14.x, 15.x] webpack-version: [latest, next] include: - node: 14.x diff --git a/package.json b/package.json index 57a5d97b..80bec2b6 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "react-intl": "^3.3.2", "react-intl-webpack-plugin": "^0.3.0", "rimraf": "^3.0.0", + "semver": "7.0.0", "webpack": "^4.0.0" }, "scripts": { diff --git a/src/index.js b/src/index.js index 09458864..a5ddcdc4 100644 --- a/src/index.js +++ b/src/index.js @@ -159,7 +159,9 @@ async function loader(source, inputSourceMap, overrides) { ); } - const config = babel.loadPartialConfig( + // babel.loadPartialConfigAsync is available in v7.8.0+ + const { loadPartialConfigAsync = babel.loadPartialConfig } = babel; + const config = await loadPartialConfigAsync( injectCaller(programmaticOptions, this.target), ); if (config) { diff --git a/test/fixtures/babelrc.mjs b/test/fixtures/babelrc.mjs new file mode 100644 index 00000000..d117b0df --- /dev/null +++ b/test/fixtures/babelrc.mjs @@ -0,0 +1,3 @@ +export default { + presets: ["@babel/preset-env"] +}; diff --git a/test/loader.test.js b/test/loader.test.js index e42567b7..370d4dc5 100644 --- a/test/loader.test.js +++ b/test/loader.test.js @@ -2,6 +2,7 @@ import test from "ava"; import fs from "fs"; import path from "path"; import rimraf from "rimraf"; +import { satisfies } from "semver"; import webpack from "webpack"; import createTestDirectory from "./helpers/createTestDirectory"; @@ -127,3 +128,56 @@ test.cb( }); }, ); + +test.cb("should load ESM config files", t => { + const config = Object.assign({}, globalConfig, { + entry: path.join(__dirname, "fixtures/constant.js"), + output: { + path: t.context.directory, + }, + module: { + rules: [ + { + test: /\.js$/, + loader: babelLoader, + exclude: /node_modules/, + options: { + // Use relative path starting with a dot to satisfy module loader. + // https://github.com/nodejs/node/issues/31710 + // File urls doesn't work with current resolve@1.12.0 package. + extends: ( + "." + + path.sep + + path.relative( + process.cwd(), + path.resolve(__dirname, "fixtures/babelrc.mjs"), + ) + ).replace(/\\/g, "/"), + babelrc: false, + }, + }, + ], + }, + }); + + webpack(config, (err, stats) => { + t.is(err, null); + // Node supports ESM without a flag starting from 12.13.0 and 13.2.0. + if (satisfies(process.version, `^12.13.0 || >=13.2.0`)) { + t.deepEqual( + stats.compilation.errors.map(e => e.message), + [], + ); + } else { + t.is(stats.compilation.errors.length, 1); + const moduleBuildError = stats.compilation.errors[0]; + const babelLoaderError = moduleBuildError.error; + t.true(babelLoaderError instanceof Error); + // Error messages are slightly different between versions: + // "modules aren't supported" or "modules not supported". + t.regex(babelLoaderError.message, /supported/i); + } + t.is(stats.compilation.warnings.length, 0); + t.end(); + }); +});