I created a small JS module which I intend to make an npm package, but for now is just on GitHub. This module is written in ES6 and SCSS, and is thus relying on webpack and babel for transpilation.
To test it, I created a separate project with a similar setup (webpack and babel). After npm installing my module, when trying to import it into my index.js, I get the following error in Chrome Developer Tools: (with x being my module's name)
index.js:11 Uncaught TypeError: x__WEBPACK_IMPORTED_MODULE_1___default.a is not a constructor
at eval (index.js:11)
at Object../src/index.js (main.js:368)
at __webpack_require__ (main.js:20)
at eval (webpack:///multi_(:8081/webpack)-dev-server/client?:2:18)
at Object.0 (main.js:390)
at __webpack_require__ (main.js:20)
at main.js:69
at main.js:72
I've looked through countless answers and tried countless solutions, to no avail. My module's setup is as follows.
.babelrc
{
"presets": [
["env", {
"targets": {
"browsers": ["ie >= 11"]
}
}]
],
"plugins": [
"transform-es2015-modules-commonjs",
"transform-class-properties"
]
}
webpack.common.js
const path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const cleanWebpackPlugin = require('clean-webpack-plugin')
const baseSCSS = new ExtractTextPlugin('main/_base.css')
const themeSCSS = new ExtractTextPlugin('main/_theme.css')
module.exports = {
entry: {
example: [
path.join(__dirname, 'src', 'example', 'index.js')
],
main: [
'idempotent-babel-polyfill',
path.join(__dirname, 'src', 'index.js')
]
},
output: {
path: path.join(__dirname, 'dist'),
filename: path.join('[name]', 'index.js')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
}
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract(
{
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
}
)
},
{
test: /\_base-scss$/,
use: baseSCSS.extract(
{
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
}
)
},
{
test: /\_theme-scss$/,
use: themeSCSS.extract(
{
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
}
)
}
]
},
plugins: [
new cleanWebpackPlugin('dist', {}),
new ExtractTextPlugin({ filename: path.join('example', 'style.css') }),
baseSCSS,
themeSCSS,
new HtmlWebpackPlugin({
inject: false,
hash: true,
template: path.join(__dirname, 'src', 'example', 'index.html'),
filename: path.join('example', 'index.html')
})
]
}
webpack.prod.js
const merge = require('webpack-merge')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const webpack = require('webpack')
const common = require('./webpack.common.js')
module.exports = merge(common, {
plugins: [
new UglifyJSPlugin({
sourceMap: true
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
],
mode: 'production'
})
package.json
{
"name": "my-module-name",
"version": "1.0.0-beta.1",
"description": "",
"main": "dist/main/index.js",
"scripts": {
"start": "webpack-dev-server --config webpack.dev.js",
"server": "node src/server",
"format": "prettier-standard 'src/**/*.js'",
"lint": "eslint src",
"build": "webpack --config webpack.prod.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Liran",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.3",
"babel-loader": "^7.1.4",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"babel-preset-env": "^1.7.0",
"clean-webpack-plugin": "^0.1.19",
"css-loader": "^0.28.11",
"eslint": "^4.19.1",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"html-webpack-plugin": "^3.2.0",
"idempotent-babel-polyfill": "^0.1.1",
"node-sass": "^4.9.0",
"prettier-standard": "^8.0.1",
"sass-loader": "^7.0.1",
"style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.5",
"webpack": "^4.6.0",
"webpack-cli": "^2.0.15",
"webpack-dev-middleware": "^3.1.3",
"webpack-dev-server": "^3.1.3",
"webpack-merge": "^4.1.2"
}
}
Any help/pointers would be greatly appreciated. If you need more information, please let me know.
If you are not the library author and are having a problem consuming another library, you may be seeing an error like this:
TypeError: [LIBRARY_NAME]__WEBPACK_IMPORTED_MODULE_3__ is not a constructor
If that's the case, you may be importing the library incorrectly in your code (it may be a problem with default exports). Double check the library docs for usage.
It may be as simple as changing this:
import Foo from 'some-library/Foo';
to this:
import { Foo } from 'some-library';
It is not working because it is missing libraryTarget and library properties. By doing that webpack know which format of module you would like to create, i.e: commonjs (module.exports) or es (export).
I would do something like:
...
output: {
path: path.join(__dirname, 'dist'),
filename: path.join('[name]', 'index.js'),
library: "my-library",
libraryTarget: "umd" // exposes and know when to use module.exports or exports.
},
...
Besides setting the libraryTarget, it may also be necessary to move the export in the JavaScript file to the default.
function MyClassName() {
...
}
export default MyClassName;
And then in the webpack configuration the library type umd ...
(Note that I have used the newer library.type instead the older libraryTarget (see https://webpack.js.org/configuration/output/#outputlibrarytarget).
const path = require('path');
module.exports = {
mode: "production",
entry: '../wherever/MyClassName.js',
output: {
library: {
name: "MyClassName",
type: "umd", // see https://webpack.js.org/configuration/output/#outputlibrarytype
export: "default", // see https://github.com/webpack/webpack/issues/8480
},
filename: 'MyClassName.min.js',
path: path.resolve(__dirname, '../wherever/target/')
},
optimization: {
minimize: true
}
};
The export default makes the class available in JavaScript like the file was embedded directly, i.e.,
<script type="text/javascript" src="MyClassName.min.js"></script>
<script type="text/javascript">
<!--
var myInstance = new MyClassName();
// -->
</script>
Disclaimer: I added this answer even though the original question is three years old by now. After encountering the "is not a constructor" issue, it took me hours of searching to find the default solution. And that was the second time, I searched and found it :D
Cf. David Calhoun's answer, if you run into this with a third-party library, you may be trying to import a CommonJS module as an ECMAScript module. The workaround there seems to be to use require instead of import, e.g., instead of
import { Foo } from 'bar'
you need to write
const Foo = require('bar')
(There may be a more elegant way to handle this, but this is what worked for me.)
For me, it was the cache issue. Just cleared the cookies, cache data and closed, reopened the browser. It worked.
In my case, the error was being caused in React when trying to invoke JS's built-in Error constructor, or in other words, basically when calling throw new Error("something").
On inspection of my code, I realised I had a component called Error in my project which was being imported into the same file. The name clash between this component and JS's built-in Error constructor was causing the error mentioned in the question.
In case something is using wepack 5 + babel 7
"webpack": "5.73.0",
"#babel/core": "7.4.4",
"#babel/preset-env": "7.4.4",
"babel-loader": "8.0.5",
AND want to use class instead function, this worked for me:
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname +"-"+this.lname;
}
}
export default Person;
In my case .babelrc was not necesary
tl;dr
Make sure that you import properly through index files.
Explanation
For me, this error was caused by importing through index files. I had multiple directories with their index.ts files that exported all the files inside the directory. These index files were accumulated/reexported by a main index.ts file so everything can be imported through it.
src/
├── index.ts
├── module1/
│ ├── index.ts
│ ├── file1.ts
│ └── file2.ts
└── module2/
├── index.ts
├── file3.ts
└── file4.ts
In file4.ts I had an import like this:
import { file1Class, file2Class, file3Class } from "src";
I had to split it into two separate imports:
import { file1Class, file2Class } from "src/module1";
import { file3Class } from "src/module2";
Related
I'm using rollup to bundle a library and I want to include external dependencies together with my code in the UMD bundle. I can't find any useful information about this in the docs. It could be that I'm missing something obvious but it seems like the docs only demonstrates how to mark relative modules as external. I've been trying to achieve this without any success. Is it doable and if yes, how?
My code making use of an external component: src/index.ts
import { ExternalComponent } from 'external-component'
function MyComponent() {
const externalComponent = ExternalComponent()
// ...
}
export default MyComponent
Desired output: bundle.umd.js
function ExternalComponent() {
// ...
}
function MyComponent() {
const externalComponent = ExternalComponent()
// ...
}
rollup.config.js
import babel from '#rollup/plugin-babel'
import typescript from 'rollup-plugin-typescript2'
import resolve from '#rollup/plugin-node-resolve'
import { terser } from 'rollup-plugin-terser'
import localTypescript from 'typescript'
const CONFIG_BABEL = {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
exclude: 'node_modules/**',
babelHelpers: 'bundled',
}
const CONFIG_TYPESCRIPT = {
tsconfig: 'tsconfig.json',
typescript: localTypescript,
}
const kebabCaseToPascalCase = (string = '') => {
return string.replace(/(^\w|-\w)/g, (replaceString) =>
replaceString.replace(/-/, '').toUpperCase(),
)
}
export default [
{
input: 'src/index.ts',
output: [
{
file: `${packageJson.name}.umd.js`,
format: 'umd',
strict: true,
sourcemap: false,
name: kebabCaseToPascalCase(packageJson.name),
plugins: [terser()],
}
],
plugins: [resolve(), typescript(CONFIG_TYPESCRIPT), babel(CONFIG_BABEL)],
},
]
package.json
{
"types": "index.d.ts",
"scripts": {
"build": "rollup -c",
"start": "rollup -c --watch",
},
"devDependencies": {
"#babel/core": "7.17.0",
"#rollup/plugin-babel": "^5.3.0",
"#rollup/plugin-node-resolve": "13.1.3",
"husky": "^4.3.8",
"npm-run-all": "^4.1.5",
"prettier": "2.5.1",
"rollup": "^2.67.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.31.2",
"typescript": "^4.5.5"
},
}
Thanks in advance,
David
I find something from the rollup documentation:
If you do want to include the module in your bundle, you need to tell Rollup how to find it. In most cases, this is a question of using #rollup/plugin-node-resolve.
But the #rollup/plugin-node-resolve doc does not help.
I am attempting to make a webpack 5 build process to create a react component library I just had a couple of things cannot seem to get working.
#1) The webpack build command works fine, and when using the inline-source-map option I can
SEE the data URL embeded in the outputted build file but when I ever I attempt to publish and test this library on NPM I always get obfuscated errors without original lines of code so I can't even tell where the errors are; what else am I missing to activate source-maps? I am using Chrome dev tools and it doesn't even tell me a source map is available for that code...
#2) Another issue I am having is after building this with webpack into the dist folder; I start another CRA test app and try to pull components out of the built library but all I get are these errors.
./src/dist/index.js
Line 1:1: Expected an assignment or function call and instead saw an expression no-unused-expressions
Line 1:112: 'define' is not defined no-undef
Line 1:123: 'define' is not defined no-undef
Line 1:190: Unexpected use of 'self' no-restricted-globals
Line 1:466: Expected an assignment or function call and instead saw an expression no-unused-expressions
Line 1:631: Expected an assignment or function call and instead saw an expression no-unused-expressions
I am aware webpack 5 stopped bundling polyfills for Node but shouldn't this code run
if I place it in the src directory of a CRA application? This is bundled code shouldn't it work in the browser/ in another React application? I targeted UMD so I thought it would work in this environment
here is all the necessary info
Webpack.config.js
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const nodeExternals = require("webpack-node-externals");
module.exports = {
entry: "./src/index.js",
devtool: "inline-source-map",
externals: [nodeExternals()],
output: {
filename: "index.js",
path: path.resolve(__dirname, "dist"),
library: {
name: "test",
type: "umd",
},
},
plugins: [new CleanWebpackPlugin()],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"],
},
},
},
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"],
include: path.resolve(__dirname, "./src"),
},
],
},
};
Package.json
{
"name": "test-lib",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "start-storybook",
"build": "webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"#babel/core": "^7.15.8",
"#babel/preset-env": "^7.15.8",
"#babel/preset-react": "^7.14.5",
"#storybook/addon-knobs": "^6.3.1",
"#storybook/react": "^6.3.10",
"babel-loader": "^8.2.2",
"clean-webpack-plugin": "^4.0.0",
"node-sass": "^6.0.1",
"path": "^0.12.7",
"sass-loader": "^12.1.0",
"webpack": "^5.58.0",
"webpack-cli": "^4.9.0",
"webpack-node-externals": "^3.0.0"
}
}
Button.js (sample component)
import React from 'react'
import PropTypes from 'prop-types';
const Button = ({message = 'Hello world'}) => (
<button>{message}</button>
)
Button.propTypes = {
message: PropTypes.string.isRequired
}
export default Button
Build entry point (index.js)
export { default as Button } from "./components/Button";
Good day all!
I am trying to setup a javascript workspace including the posibility to run test script using npm, webpack (and mocha for tests).
So my project structure looks someting like (npm generated files are omitted):
root
|- src
| |- main.js
| |- MyClass.js
|- test
| |- test.js
|- package.json
|- webpack.config.js
The main.js script is building and debugging fine. But the test script is giving me problems.
In short, I import classes from the project (from the src directory) for testing. But it cannot resolve it (eventhough intellisense of vscode is having no issues at all). So if my test-script looked something like:
import { MyClass } from 'MyClass'
/* testing stuff */
Intellisense is perfectly capable of resolving the location (as configured in the jsconfig.json), but eventhough I set the src directory as include-rule or as alias, webpack is not able to resolve it and tries to search in the /test directory instead (and in recursive order all its parent-directories, failing in the same manner).
So the question is how to let webpack resolve for 'nephew' directories?
(If there is an easier way to use mocha than with the current combined scripts, it would suffice in this case as well. So feedback on that is also welcome, but I defenitly would love to find the answer to the original question)
Here is the webpack.config.js content
const path = require('path');
{
name: "myProject_test",
mode: "development",
entry: path.resolve(__dirname, "./test/test.js"),
devtool: 'source-map' : '',
output:
{
clean: { dry: true },
path: path.resolve(__dirname, root, source.outputDir),
filename: "[id]/[name].js",
},
module:
{
rules:
[
{
test: /.jsx?$/,
include: [path.resolve(__dirname, "./test"), path.resolve(__dirname, "./src")],
exclude: [path.resolve(__dirname, "./dist"), path.resolve(__dirname, "./test/test-dist"), path.resolve(__dirname, "./node_modules")],
loader: 'loader-type',
options: { /* All loader types follow this pattern; so the rest is omited for brevety, but basically this includes all the loaders required for correct compiling */ }
}
],
},
resolve:
{
alias:
{
"*": [path.resolve(__dirname, "./src/*"), path.resolve(__dirname, "./test/*")],
},
extensions: ['.json', '.js', '.jsx', '.scss', '.sass', '.html', '.htm']
},
devServer:
{
contentBase: [path.resolve(__dirname, "./test"), path.resolve(__dirname, "./test/test-dist")],
/* Other server properties to make this work with server utility */
}
}
And here the package.json file content
{
"name": "MyProject",
"version": "0.0.1",
"description": "some description",
"dependencies": {},
"scripts": {
"test": "webpack && mocha test/test-dist --require source-map-support/register --reporter spec --check-leaks --recursive && rm -rf test/test-dist",
"debug": "webpack serve",
"start": "webpack --watch",
"build": "webpack"
},
"devDependencies": {
"#babel/core": ">=7.x",
"#babel/preset-env": ">=7.x",
"babel-loader": ">=8.x",
"cross-env": ">=7.x",
"css-loader": ">=6.x",
"html-loader": ">=2.x",
"resolve-url-loader": ">=4.x",
"style-loader": ">=3.x",
"sass-loader": ">=12.x",
"sass": ">=1.x",
"mini-css-extract-plugin": ">=2.x",
"extract-loader": ">=5.x",
"webpack": ">=5.x",
"webpack-cli": ">=4.x",
"webpack-dev-server": ">=3.x",
"worker-loader": ">=3.x",
"source-map-support": ">=0.x",
"mocha": ">=8.x",
"should": ">=13.x"
}
}
I'm kind of new to testing library, and recently started studying Jest. I'm currently trying to implement vanilla javascript project with jest.
I know 'mocking' an async API call in jest is best practice, but I wanted to actually call API using fetch to see if jest works correctly. But I got stuck on 'fetch' request. Need to remind you that my project is not node project, just plain vanilla javascript project.
Before moving on to actual test code, since I'm using babel and webpack on my project. Here's .bablerc.js and webpack.config.js implementation.
.babelrc.js
module.exports = {
presets: [
[
'#babel/env',
{
targets: {
browsers: ['> 0.25%, not dead'],
},
useBuiltIns: 'usage',
corejs: 3,
shippedProposals: true,
},
],
],
};
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/js/index.js',
output: {
path: path.resolve(__dirname, 'public'),
filename: 'static/js/main.js',
},
module: {
rules: [
{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/,
},
{
test: /\.(sc|c)ss$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
],
},
devServer: {
contentBase: path.resolve(__dirname, 'public'),
inline: true,
hot: true,
watchOptions: {
poll: true,
ignored: '/node_modules/',
},
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Typing Game',
minify: {
collapseWhitespace: true,
},
hash: true,
template: './src/index.html',
}),
new MiniCssExtractPlugin({ filename: 'static/css/styles.css' }),
],
};
With project configuration above, webpack and webpack-dev-server worked perfectlly and could retrieve completely built html, css and js files. After checking everything except Jest works perfectly, I implemented simple API call function that gets list of words in array,
export const getWordsAPI = () =>
fetch(
'https://server-api-address'
).then((res) => res.json());
And tried to call the api function on my jest test code.
import { getWordsAPI } from '../src/js/api';
describe('Integration with getWords API', () => {
test('Get Word List', async () => {
const result = await getWordsAPI();
expect(result).toEqual([
{
text: 'hello',
},
{
text: 'world',
}
]);
});
});
But, I continuously got this 'fetch is not defined' error.
ReferenceError: fetch is not defined
> 1 | export const getWordsAPI = () =>
| ^
2 | fetch(
3 | 'https://server-api-address'
4 | ).then((res) => res.json());
at getWordsAPI (src/js/api.js:1:28)
at _callee$ (__tests__/api.test.js:5:26)
at tryCatch (node_modules/regenerator-runtime/runtime.js:63:40)
at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:293:22)
at Generator.next (node_modules/regenerator-runtime/runtime.js:118:21)
at asyncGeneratorStep (__tests__/api.test.js:11:103)
at _next (__tests__/api.test.js:13:194)
at __tests__/api.test.js:13:364
at Object.<anonymous> (__tests__/api.test.js:13:97)
I tried everything to solve this problem, including jest-fetch-mock but couldn't solve the problem. when I applied jest-fetch-mock to test code, I got new error which is this.
invalid json response body at reason unexpected end of json input
I eventually ended up using isomorphic-fetch library to make fetch work on my test code, which makes me uncomfortable.
import 'isomorphic-fetch';
import { getWordsAPI } from '../src/js/api';
describe('Integration with getWords API', () => {
...
}
I understand fetch is not defined error happening on nodejs environment, since there is not fetch provided by node, but this is vanilla javascript project. fetch is provided by default on browser, and should work without any additional work. But why is this error happening? I don't know what is causing this problem, either babel or webpack or even jest itself.
Please teach me what I'm missing. Probably I'm missing the main concept of Jest architecture, related to this problem. Waiting for anyone's response
ps. In case you need to know what version of libraries I'm using in my project, here's my package.json file. Other than libraries, I'm using WSL2 on Windows OS, and using npm instead of yarn.
{
"name": "typing_game",
"version": "1.0.0",
"description": "Typing Game by Vanilla Javascript",
"main": "index.js",
"author": "piecemakerz <piecemakerz#naver.com>",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --open",
"build": "webpack",
"test": "jest"
},
"devDependencies": {
"#babel/core": "^7.12.3",
"#babel/preset-env": "^7.12.1",
"#types/jest": "^26.0.15",
"babel-jest": "^26.6.3",
"babel-loader": "^8.2.1",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^5.0.1",
"html-webpack-plugin": "^4.5.0",
"jest": "^26.6.3",
"mini-css-extract-plugin": "^1.3.1",
"prettier": "^2.1.2",
"sass-loader": "^10.1.0",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"core-js": "^3.7.0",
"isomorphic-fetch": "^3.0.0",
"sass": "^1.29.0"
},
"jest": {
"transform": {
"^.+\\.js?$": "babel-jest"
}
}
}
I'm working on a browser-based project that needs to be IE11-compatible (sigh). Webpack is choking on async/await. Here is my console's output:
Based on your code and targets, added regenerator-runtime.
...
Module not found: Error: Can't resolve 'regenerator-runtime/runtime'
I've looked at many SO questions similar to mine, without luck. Many recommend using #babel/polyfill which I am avoiding since it has been deprecated.
What is causing this issue? I expect it could be fixed by manually importing regenerator-runtime/runtime, but it seems one of the main selling points of babel-env is NOT having to manually import polyfills, so I assume I'm missing a step. Thank you!
Here is what I am attempting to run, which is being imported into another file:
class Fetcher {
constructor() {
this.form = document.querySelector('form');
this.form.addEventListener('submit', this.onSubmit.bind(this));
}
async onSubmit(event) {
event.preventDefault();
const apiResponse = await fetch(`${WP_url}/api`);
const apiJson = await apiResponse.json();
console.log(apiJson);
}
}
export default Fetcher;
webpack.config.js:
const path = require('path');
function pathTo(filepath) {
return path.join(__dirname, filepath);
}
module.exports = function(env, argv) {
const isProd = Boolean(argv.mode === 'production');
const config = {
entry: {
index: [
pathTo('index.js'),
],
},
externals: {
jquery: 'jQuery',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'#babel/preset-env',
{
corejs: 3,
debug: true,
targets: {
browsers: [
'IE 11',
],
},
useBuiltIns: 'usage',
},
],
],
},
},
],
},
optimization: {
minimize: isProd,
},
output: {
filename: '[name].js',
path: pathTo('web'),
},
};
return config;
};
package.json
{
"private": true,
"dependencies": {
"core-js": "^3.4.1",
"focus-within-polyfill": "^5.0.5"
},
"devDependencies": {
"#babel/core": "^7.7.2",
"#babel/preset-env": "^7.7.1",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.0.6",
"css-loader": "^3.2.0",
"eslint": "^6.6.0",
"mini-css-extract-plugin": "^0.8.0",
"node-sass": "^4.13.0",
"sass-loader": "^8.0.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
},
"scripts": {
"dev": "webpack --mode=development --display-modules",
"dev:watch": "npm run dev -- --watch",
"prod": "webpack --mode=production --display-modules",
"prod:watch": "npm run prod -- --watch"
}
}
Simply running npm i regenerator-runtime fixed it, actually.
With useBuiltIns: 'usage', having all the import statements wasn't necessary I guess.
¯\_(ツ)_/¯
Just add import 'regenerator-runtime/runtime' in the file where you have the async/await.
In my case, your answer wasn't enough and I needed to set babel sourceType to unambiguous as suggested here to allow a correct compilation of the project. This option was required because the #babel/runtime/regenerator/index.js file exports its reference using module.exports = require("regenerator-runtime"); that breaks ES6 compilation.
Another useful note resolving a similar but unrelated compilation issue was to use /node_modules\/(css-loader|#babel|core-js|promise-polyfill|webpack|html-webpack-plugin|whatwg-fetch)\// as exclude for the babel rule to avoid resolution loops without loosing external libraries compilation (when necessary) as suggested here.
TL;DR
In your specific case the babel rule would become:
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
sourceType: 'unambiguous',
presets: [
['babel/preset-env', {
corejs: 3,
debug: true,
targets: {
browsers: [ 'IE 11', ],
},
useBuiltIns: 'usage',
}],
],
},
},
I started getting this error when added transpileDependencies: ['openplayerjs'], to my vue.config.js, as Babel with #vue/cli-plugin-babel/preset won't touch dependencies in node_modules, go figure why. Installing regenerator-runtime did not help, and I thought the issue lied in Yarn's pnp modules:
This dependency was not found:
* regenerator-runtime/runtime.js in /Volumes/Backup/home/Documents/.yarn/unplugged/openplayerjs-npm-2.9.3-aa4692035d/node_modules/openplayerjs/dist/esm/media.js, /Volumes/Backup/home/Documents/.yarn/unplugged/openplayerjs-npm-2.9.3-aa4692035d/node_modules/openplayerjs/dist/esm/media/ads.js and 1 other
To install it, you can run: npm install --save regenerator-runtime/runtime.js
so I tried unplugging everything via yarn unplug <module_name>, still did not work.
Eventually changing useBuiltIns: 'usage' to useBuiltIns: 'entry' in babel.config.js solved it straight away.
Following the official documentation:
Install required packages.
npm install --save-dev #babel/plugin-transform-runtime
npm install --save #babel/runtime
Add plugin to the configuration file.
{
"plugins": ["#babel/plugin-transform-runtime"]
}
This is officially recommended method, more available in the mentioned documentation.