Webpack with Babel lazy load module using ES6 recommended Import() approach not working - import

I'm trying to do code splitting and lazy loading with webpack using the import() method
import('./myLazyModule').then(function(module) {
// do something with module.myLazyModule
}
I'm getting
'import' and 'export' may only appear at the top level
Note top level imports are working fine, i'm just getting an issue when I try and using the dynamic variant of import()
var path = require('path');
module.exports = {
entry: {
main: "./src/app/app.module.js",
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name]-application.js"
},
module: {
rules: [
{
test: /\.js$/,
use: [{
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}]
}
]
},
resolve : {
modules : [
'node_modules',
'bower_components'
]
},
devtool : "source-map"
}
EDIT:
If I change it so the syntax reads, it works.... but the chunk comments don't work to label the bundle. I'm confused because the documentation says the the following is depreciated.
The use of System.import in webpack did not fit the proposed spec, so
it was deprecated in webpack 2.1.0-beta.28 in favor of import().
System.import('./myLazyModule').then(function(module) {
// do something with module.myLazyModule
}

You need the plugin syntax-dynamic-import to be able to use the import() function with Babel.
Install it with:
npm install --save-dev #babel/plugin-syntax-dynamic-import
And add it to your plugins:
{
presets: ['es2015'],
plugins: ['#babel/plugin-syntax-dynamic-import']
}

Related

How to pass options to babel plugin transform-modules-commonjs?

I create a Vue 2 project by Vue-Cli 5, then I want to remove "use strick" in the complied code.
As I Know, the #babel/plugin-transform-strick-mode may be enabled via #babel/plugin-transform-modules-commonjs, and the plugin is included in #babel/preset-env under the modules option.
But the Vue-Cli used a preset #vue/babel-preset-app by a plugin #vue/cli-plugin-babel for babel.
So my question is How pass strictMode: false as an option to the transform-modules-commonjs by #vue/babel-preset-app which preset is in the #vue/cli-plugin-babel ?
module.exports = {
presets: [["#vue/cli-plugin-babel/preset", { modules: "auto" }]],
plugins: [
// I tried this way, but it throw many errors like:
/**
ERROR in ./node_modules/axios/dist/node/axios.cjs 11:15-32
Module not found: Error: Can't resolve 'stream' in 'D:\workspace\cqset_offical_website\node_modules\axios\dist\node'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "stream": false }
*/
["#babel/plugin-transform-modules-commonjs", {}],
[
"component",
{
libraryName: "element-ui",
styleLibraryName: "theme-chalk",
},
],
],
};

Webpack 5 "dependOn" and target: "es5" appear to be incompatible

I'm having trouble getting Webpack 5 to output es5 compatible code while also using the "dependOn" entry parameter.
I'm using Babel to transpile my code, which works fine, but unless I set the webpack target as "es5", webpack itself outputs incompatible code.
I'm using the entry parameter "dependOn", which behaves as expected with target: "web", but as soon as I change that to "es5" I get
"Error in main.build.js from Terser" and
"Unexpected token: punc(:) [main.build.js:3,9]".
Removing the "dependOn" parameter allows it to compile, but then I get my vendor libraries added to each entry.
Here is a minimal webpack config that reproduces the issue (commenting out either target: "es5" or dependOn: "vendor" fixes it):
const path = require('path');
module.exports = {
mode: "production",
target: "es5",
entry: {
vendor: "./src/test.js",
main: {
dependOn: "vendor",
import: ['./src/main.js']
}
},
output: {
filename: '[name].build.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
};
"test.js" and "main.js" can contain anything, the build still fails if they just have a "console.log" statement in each.
My package devDependencies contains the following:
"#babel/core": "^7.14.3", "#babel/preset-env": "^7.14.2", "babel-loader": "^8.2.2", "webpack": "^5.37.1", "webpack-cli": "^4.7.0".
And my .babelrc contains {"presets": ["#babel/preset-env"]}
This can be resolved by changing
target: "es5"
To
target: ["web", "es5"]
The need for both targets isn't explicitly mentioned in the relevant documentation (https://webpack.js.org/configuration/target/), so hopefully this will help anyone with the same problem.

Unable to resolve module when using babel module resolver + eslint + index files in react application

I am trying to use babel module resolver plugin with eslint + create react app but I am unable to start the application, getting the error
internal/modules/cjs/loader.js:1237
throw err;
^
SyntaxError: C:\Users\enisr\Desktop\projects\pcPartPicker\jsconfig.json:
Unexpected token } in JSON at position 166
at parse (<anonymous>)
I have set up a git repo showcasing the problem https://github.com/sgoulas/pcPartPicker
I have read the instructions in the docs and in the original repository and I am unable to configure it correctly.
My configuration files are the following:
.babelrc
{
"plugins": [
["module-resolver", {
"extensions": [
".js",
".jsx",
".es",
".es6",
".mjs"
],
"root": ["./src"],
"alias": {
"#components": "./src/components"
}
}
]
]
}
jsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"*": ["src/*"],
"#components/*": ["./src/components/*"],
}
}
}
webpack.config.dev.js
var path = require("path");
module.exports = {
include: path.appSrc,
loader: require.resolve("babel-loader"),
options: {
plugins: [
[
"module-resolver",
{
root: ["./src/App"],
alias: {
"#components": "./src/components",
},
},
],
],
cacheDirectory: true,
},
};
My component:
import { GPUtable, CPUtable } from "#components/Tables";
const App = () => {
return (
<>
<GPUtable />
<CPUtable />
</>
);
};
export default App;
There are some minor fixes you need to make (below), but the main issue is that Create React App does not expose the webpack config, you'll need to eject to edit that.
npm run eject
Merge the babel configs: delete the babel key + value at the bottom of the package.json, and paste the value into your bablrc ("presets": ["react-app"],).
Add import React from 'react'; to the top of App.js
Confirmed locally that the app will run.
Other suggested fixes
Your jsconfig has a trailing comma after the array value in #components/*. You need to remove it because JSON doesn’t support them.
You need to fix the include path in weback.config.dev.js. appSrc isn't something defined on the node path module. Try using path.resolve(__dirname, 'src') - the example in their docs is creating/importing a paths object with appSrc pointing to this value.
You're missing test: /\.(js|jsx|mjs)$/, in webpack.config.dev.js.

swiperjs es module build doesn't work in IE11 browser

I am using webpack with babel to transpile modules and after adding swiper npm package to the build, IE11 browser stopped working because dom7 dependency is not transpiled properly. This is pointed out on the swiper's get started page, however it is not clear what has to be done to fix the problem.
After couple days of research and multiple attempts, I've finally got it working.
Important thing to note is that you must use babel.config.js instead of .babelrc so that node_modules could be included into build.
The final configuration:
babel.config.js (relevant section only):
module.exports = {
"presets": [
["#babel/env", {
"targets": {
"ie": "11"
}
}],...
webpack.config.js (relevant section only):
test: /\.js$/,
exclude: /node_modules\/(?!(swiper|dom7)\/).*/,
rules: [
{
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true,
babelrc: false,
rootMode: 'upward'
}
}]
}
]
Here is the article which got me to the right direction (see comment from RyanGosden) - https://www.bountysource.com/issues/79144083-not-working-in-ie11
Hope that helps other people to save some time!
Update in 2022:
Previous answer was correct, but swiper 7 adds a new esm dependency named ssr-window. So it needs to be added as below:
webpack.config.js (relevant section only):
test: /\.js$/,
exclude: /node_modules\/(?!(swiper|dom7|ssr-window)\/).*/,
rules: [
{
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true,
babelrc: false,
rootMode: 'upward'
}
}]
}
]

Webpack 2 resolve alias

I have a little problem regarding resolving aliases in webpack 2. No matter what i do i cant resolve this. Here is the relevant code:
/* webpack.mix.js */
mix.webpackConfig({
module: {
rules: [
{
test: /\.js$/,
loader: 'eslint-loader'
}
]
},
resolve: {
root: path.resolve(__dirname),
// path is reqired at the beggining of file
alias: {
config: 'src/assets/js/config', // this is a config folder
js: 'src/assets/js'
}
}
});
/* router.js */
import { DashboardRoute } from 'config/route-components'
// this import is unresolved
The resolve.root option no longer exists in webpack 2. Instead it is merged into resolve.modules (from the official Migration Guide). Webpack even throws an error that it's not a valid property. If you want to be able to import from your root directory you would change the resolve config to:
resolve: {
alias: {
config: 'src/assets/js/config',
js: 'src/assets/js'
},
modules: [
path.resolve(__dirname),
'node_modules'
]
}
Alternatively you can use an absolute path in your resolve.alias like so:
resolve: {
alias: {
config: path.resolve(__dirname, 'src/assets/js/config'),
js: path.resolve(__dirname, 'src/assets/js')
}
}
Try this:
resolve: {
root: [
'node_modules',
path.resolve('src') // Resolve on root first
],
alias: {
config: 'src/assets/js/config', // this is a config folder
js: 'src/assets/js'
}
}
In ionic 3 (version 3.13.3), in order to get alias mapping working, you will have to define path mapping both in webpack.config.js & tsconfig.json
Please refer complete answer here question here