After running my code through webpack it contians arrow functions. I need the code to work in ie11 so I need to get rid of the arrow functions.
I'm using babel-loader for all .js files.
I wrote a loader to check code for arrow functions and ran it after the babel-loader and didn't get any arrow functions, so I know the output from babel is good.
I've also tried babel-polyfill and the babel plugin for transforming arrow funtions.
As I know the babel-loader outputs good code I suspect it might be a plugin, but I can't just disable them to test as that breaks the build.
Webpack plugins used in dev:
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
The problem also appears in prod as well, but fixing it in dev should tell me how to fix it in prod as well.
I don't know of anywhere else the arrow function could be coming from, so I expect to, in essence, get code that works on ie11, but there's arrow functions coming from somewhere so it doesn't work.
It's not my code, so I can't just post it all. I can, however, post relevant snippets, but I don't know where the problem is so I don't know what's relevant yet.
I had the same problem and found the cause and solution.
Cause
babel-loader converts the grammar of es6 and higher to es5. However, because the conversion is done by the loader, the conversion occurs only in each file before it is bundled.
After the loader completes the conversion, webpack starts to bundle. However, webpack does not care about target version of babel-loader when it bundles files. It just bundles file with grammar of it's default ECMA version(which could be es6 or later). It was the reason why bundled result includes es6 grammar such as arrow function.
Initial Step
file1 (es6)
file2 (es6)
file3 (es6)
After loader works
file1' (es5)
file2' (es5)
file3' (es5)
After webpack bundles files
bundled file (es6)
Solution
You can just simply add target: "es5" in webpack.config.js to handle this. After that, webpack bundles file in grammar of es5
// .babelrc
{
"presets": ["#babel/preset-env"]
}
// webpack.config.js
module: {
...
target: "es5", // include this!!
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
}
]
}
In webpack 5:
module.exports = {
target: ['web', 'es5']
}
target is positioned at the root of the config schema and needs to know whether it targets a node or web environment
References:
https://webpack.js.org/configuration/target/
Webpack 5 "dependOn" and target: "es5" appear to be incompatible
You can use babel. Since arrow functions comes with es6 , you can use babel to convert es5. Also this link could help to Webpack not converting ES6 to ES5.
Given below webpack config is what I used for babel.
module: {
loaders: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
babelrc: false,
presets: ["#babel/preset-env", "#babel/preset-react","es2015"]
}
}
]
}
Related
I have this:
{
test: /\.jsx?$/,
include: [APP_ROOT],
exclude: [path.resolve('./node_modules')],
use: {
loader: 'babel-loader',
options: {
plugins: [],
},
},
},
If I don't exclude node_modules, it'll throw Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'. However, I don't trust that every package is transpiled properly. Therefore, I want to run everything through Babel again after Webpack combines everything.
My understanding is that babel-loader runs Babel on each file individually. This causes the error above. If I run Babel on the whole output file, it works fine. Preferably, I'd want to run Babel on the output before Uglify/Terser.
How do I do this?
I have JavaScript code and source maps generated from TypeScript code (using tsc).
I then have a second compilation step which bundles the code using webpack.
I have enabled source maps in webpack.config.js:
module.exports = {
devtool: "source-map"
}
The generated source map isn't entirely right.
Webpack is not taking into account the existing source maps that have been generated from TypeScript code.
This results in a mapping to the JavaScript code instead of the TypeScript code.
How can I get the Webpack source map to include existing mapping?
EDIT:
After renaming my question, and searching for my renamed question on Google, I found an answer.
You can use a preloader with webpack called source-map-loader: https://webpack.js.org/loaders/source-map-loader/
However, after installing source-map-loader and updating webpack.config.js to the following, the existing source maps are still not used:
module.exports = {
devtool: "source-map",
module: {
rules: [
{
test: /\.js$/,
use: ["source-map-loader"],
enforce: "pre"
}
]
}
}
My guess is that because the files my existing source map point to are located outside the entry directory in webpack.config.js, they are ignored...?
If you transpile the typescript as part of webpack, you will get the source maps with it.
devtool: 'source-map',
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: ([
{
loader: 'awesome-typescript-loader',
options: { configFileName: 'tsconfig.json' }
},
you need devTool: 'source-map' in webpack
and the "sourceMap": true in tsconfig.json
devtool: 'cheap-module-eval-source-map',
provides a faster build to generate source maps in development. But it will put the source mapping inline. So not for production.
So the big question. Why have a step separated from webpack?
If you use AOT compilation with angular (with the ngc command from #anguler/compiler), and produce .map files in the aot folder, then you want to reuse the map files. I can tell you I tested it to work with the solution below.
Then this will make it work:
{
test: /\.js$/,
use: ["source-map-loader"],
enforce: "pre"
},
And it is important you have sourceMap: true in tsconfig, and in the minimizer if you use one:
optimization: {
minimizer: [
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true, // Must be set to true if using source-maps in production
terserOptions: {
// https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
}
I have a tsconfig.json in development
a tsconfig_ao1.json for ngc command
I have a tsconfig_ao2.json to compile with aot the main.ts using the aot folder. And I use ngc outside of webpack because I could not use #ngtools/webpack inside webpack without issues.
If you are doing something else, you ened to understand the source-map-load will only load source maps if the files it test matches has source maps, and if the files art part of the tree loaded from the entry. There must be an import from the main.ts to the file that is source mapped.
I migrated to Webpack 4 and set up everything according to the Docs, however, my vendors.js chunk is not getting compiled like the main.js chunk.
I have placed the vendors into the optimization.splitChunks.cacheGroups object, as the docs suggested, but didnt find a way to make these "cacheGroups" get compiled with babel.
My problem is that one of the libraries has a ES6 class and now IE11 isnt working due to this fact.
My webpack optimization object looks like:
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true
},
vendor: {
name: 'vendor',
test: /[\\/]node_modules[\\/]/,
chunks: 'all',
enforce: true
}
}
}
}
Is there a way to force webpack to compile vendors with babel as well?
Regards
you should have posted the entire webpack config to give people more context.
Anyways, optimization step has very little to do with the actual transpiling. Your vendor chunk is set to only include stuff from node_modules which is almost never processed (unless you specifically tell babel-loader to include a certain package).
Since I do not know how you configured your babel-loader I would suggest something along these lines:
{
test: /\.js$/,
exclude: (file) => {
return /node_modules/.test(file) && !file.includes("/node_modules/my-es6-module/");
}
}
The idea is to exclude all files containing node_modules unless the file path contains the name of your specific module which you do need to process with babel.
In general, having an ES6 code published to npm is a very bad practice and should be avoided at all costs.
If this is not enough, please do update your question with your webpack config to give us more insight into your setup.
I have an entire legacy AngularJS 1.x application that used to run through gulp and babel. We are transitioning to the newer Angular 2+ but I'm running into an issue trying to get Webpack to actually find and compile the legacy files. I've tried following instructions which are all almost identical like this video:
https://www.youtube.com/watch?v=H_QACBSqRBE
But the webpack config simply doesn't do anything to the existing files. Is there a way to grab a WHOLE FOLDER of older components, that DO NOT have any imports or exports? I feel like entry is supposed to follow the import dependency path but that just doesn't exist for older AngularJS 1.x projects.
Errors are NOT being thrown during the build it just...doesn't transpile or polyfill.
example of what that section of the config looks like:
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}
]
We did this recently. We created "dummy" entry point files to avoid having to change all of our AngularJS files to have require/import statements.
./entry-points/feature1.ts
export const importAll = (r: any): void => {
r.keys().forEach(r);
};
importAll(require.context('./app/feature1', true, /module\.js$/));
importAll(require.context('./app/feature1', true, /(^(?!.*(spec|module)\.js).*\.js)$/));
webpack.config.js
entry: {
'feature1': './entry-points/feature1.ts'
}
More detail here
I can successfully transpile es6 modules -> System.Register format using babel cli.
I would like to be able to transpile to System.Register format using babel from Webpack.
.babelrc
{
"presets": ["es2015"],
"plugins": ["transform-es2015-modules-systemjs"]
}
webpack.config.js
.....
.....
loaders: [ {
test : /.js$/,
exclude : /node_modules/,
loader : 'babel-loader',
query: {
presets: ['es2015']
}
}
]
.....
.....
After running 'webpack', a warning is returned System.register is not supported by webpack.
I know this is self explanatory, my question is (which i have been unable to find the answer to after searching / investigating) -
Is this something that is going to be supported by webpack? Or if it is supported, what am i doing wrong?
Thanks,
Pretty out-of-date answer, but you could try "commonjs". It gets worked for me.