Use Template Strings with webpack [Javascript] - javascript

I'm fairly new to webpack, and when compiling my code I came across this error.
ERROR in Error: Child compilation failed:
Module build failed (from ../node_modules/html-loader/index.js):
Error: Line 539: Unexpected identifier
And this is the line that its referring too.
return `background: linear-gradient(to bottom right, ${this.gradientStart}, ${this.gradientEnd});`
Is it possible to allow Template Strings in Webpack?
This is the inside of my webpack config
const html = {
test: /\.(html)$/,
// exclude: /\.html$/,
use: [
{
loader: 'html-loader',
options: {
interpolate: true,
},
},
],
};

Template strings are a feature of es2015. Webpack does not understand es2015 by default to ensure compatibility with as many legacy devices as possible. You need to use a loader that will transpile es2015 into an older version of javascript. You can use "babel-loader" with the preset webpack environment that has support for many features of modern javascript.
You need to download #babel/core & #babel/preset-env for webpack by running the following command:
npm install --save-dev -D babel-loader #babel/core #babel/preset-env webpack
You need to add the following to your webpack.config.js
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}
]
},

Related

webpack babel loader with eslint loader

I'm using webpack babel-loader with es-lint like so
{
test: /\.(js)$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader'],
},
however in the babel-loader i see on webpack that i have to pass options like so
options: {
presets: ['#babel/preset-env']
}
but since i'm using an array of loaders i can't use this option, or since i'm using eslint with babel loader i don't need this #babel/preset env ?
You may still want to use #babel/preset even with eslint-loader
#babel/preset-env is a smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms (and optionally, browser polyfills) are needed by your target environment(s). This both makes your life easier and JavaScript bundles smaller! (source)
The eslint-loader will make all code bundled by Webpack syntax checked by eslint (following your eslint config).
You can either keep babel configuration in a separate file .babelrc.json:
{
presets: [
'#babel/preset-env'
]
}
or use the webpack configuration:
use: [{
loader: 'babel-loader',
options: { presets: ['#babel/preset-env'] },
}, {
loader: 'eslint-loader'
}]

How to resolve 'class constructor cannot be invoked without new' error when building with svelte, babel, and webpack

I'm trying to get svelte, webpack, and babel to work together. I am producing the minified bundle, however, this bundle is throwing errors upon loading it up in the browser. This needs to be compatible with IE11 while using ES6 syntax.
I get
Class constructor I cannot be invoked without 'new'
The pertinent parts of my webpack looks as follows
{
test: /\.(js|jsx|mjs|svelte)?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
configFile: path.resolve(__dirname, 'babel.config.js')
}
}
]
},
{
test: /\.svelte$/,
exclude: /node_modules/,
use: {
loader: "svelte-loader",
options: {
emitCss: false,
hotReload: false
},
},
},
babel.config is as follows
module.exports = {
plugins: [
'#babel/plugin-proposal-class-properties',
'angularjs-annotate',
'lodash'
],
presets: [
['#babel/preset-env', {
useBuiltIns: 'usage',
corejs: { version: 3, proposals: true }
}],
'#babel/preset-react'
]
};
The svelte file itself is pretty basic
<script>
export let name = "World";
</script>
<h1>Hello {name}!</h1>
UPDATE
I can get it to run by excluding transform-classes in babel config
exclude: ['transform-classes'],
However, this of course breaks IE11.
You will need to update the webpack-cli and html-webpack-plugin versions in your package.json:
"webpack-cli": "^4.5.0",
"html-webpack-plugin": "^5.1.0",
Then, delete your node_modules and package-lock.json files and run a new npm install
Simply do this:
$ yarn remove webpack-cli && yarn add --dev webpack-cli
This will remove the old cli version, re-install the new one and compile everything afresh. Problem solved

Webpack gives eslint errors while using npm link

I have a multi-package project set up, where I have one JavaScript package that relies on a TypeScript library. Initially I installed Sinopia and was reinstalling the library every time I made changes to it. Then I saw npm link and thought that it would be easier for development. Unfortunately, when I linked the library (using npm link ../typescript-package) and built, it gives an error:
ERROR in ../typescript-package/dist/index.js
Module build failed: Error: No ESLint configuration found.
Since they are separate packages, I'm not quite sure why Webpack is trying to apply eslint to this package. Here is my webpack.common.js file (using merge and the dev vs prod configs shouldn't matter):
// webpack.common.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const babelOptions = {
presets: ['react', 'es2015', 'stage-0'],
sourceMaps: true,
retainLines: true,
};
module.exports = {
entry: {
solver: './source/index.jsx',
},
output: {
path: `${__dirname}/dist`,
filename: '[name].js',
publicPath: '/dist/',
},
resolve: {
modules: ['source', 'node_modules/'],
extensions: ['.js', '.jsx', '/index.jsx', '.json', '.ts', '/index.ts', '.scss', '/index.scss', '.css'],
},
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader',
options: babelOptions,
},
{
loader: 'eslint-loader',
options: {
emitWarnings: true,
},
},
],
exclude: /node_modules/,
}, {
test: /\.js$/,
loader: 'source-map-loader',
enforce: 'pre',
exclude: /node_modules/,
}, {
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
minimize: true,
localIdentName: '[local]_[hash:base64:5]',
},
}, {
loader: 'sass-loader',
options: {
includePaths: ['source/design'],
},
}],
}),
},
],
},
plugins: [
new ExtractTextPlugin({
filename: '[name].css',
allChunks: true,
}),
],
node: {
global: true,
},
};
I can also provide other config or package.json files if need be.
Way 1 - Webpack recommendation
According to webpack doc : https://webpack.js.org/configuration/module/#rule-conditions
Be careful! The resource is the resolved path of the file, which means symlinked resources are the real path not the symlink location. This is good to remember when using tools that symlink packages (like npm link), common conditions like /node_modules/ may inadvertently miss symlinked files. Note that you can turn off symlink resolving (so that resources are resolved to the symlink path) via resolve.symlinks.
So according to it you can disable symlink : https://webpack.js.org/configuration/resolve/#resolvesymlinks
Way 2 - Fancy hack
But maybe you need symlinks for your project. So, I use my eslint rule like this :
{
test: /\.js$/,
enforce: 'pre',
use: 'eslint-loader',
include: path.resolve(__dirname), // <-- This tell to eslint to look only in your project folder
exclude: /node_modules/
}
Plus obviously your own config of this loader.
I was dealing with this, as well. I'm not exactly sure why ESLint is looking for the config file in the external package (I would expect the local rc file to be adequate) but the symlink created by npm link takes the external package out of ./node_modules/, which otherwise would have been excluded by the loader.
The fix I've come up with is to copy the package into ./node_modules/. It then gets filtered out through the excludes rule in your Webpack config.
I know this is incredibly inelegant, and shouldn't be "good enough", but I've spent some time trying to get around this issue, and this is the best I was able to come up with. Until something better comes along, you can at least get moving on more pressing issues.
You can also add a .eslintignore file and add the real path to the linked module
// Content of .eslintignore
C:/path/to/your/linked/module
This is needed, because webpack resolves the module by its real path and not by the path in the node_modules folder (see webpack docs). Usually eslint ignores node_modules by default, but because of that it does not work here.

webpack how to run babel-loader on files outside the project directory?

I am using webpack2, babel-loader
import something from '../../customPackageOutsideProjectDirectory';
the above line of code gives the following error:
Module build failed: Error: Parse Error: Line 1: Illegal import declaration
at throwError (/Users/sahilsharma/workspace/projectTry/node_modules/jstransform/node_modules/esprima-fb/esprima.js:2823:21)
The error is probably because of lack of .babelrc file outside the project directory.
How to get this package loaded correctly from outside ?
The .babelrc file isn't necessary if you config Babel in webpack using the options:
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
}
]
}
https://github.com/babel/babel-loader

Babel 6 presets specified in .babelrc not working

as the title suggests, basically according to the docs, with the new Babel 6 we are now supposed to pass in plugins/presets since by default it would not do anything with our code.
So I created a .babelrc file in my project directory with the following (just like in the docs)
{
"presets": ["es2015"]
}
However this would not work.
Since I'm using webpack and babel-loader, I came across a different answer that suggested to put something like this in the webpack config:
{
test: /\.js$/, exclude: /node_modules/, loader: "babel", query: {
presets: ["es2015"]
}
}
And this works.
So my question is whether this is a bug in the new Babel or there is something obviously wrong that I'm missing? I used to use Babel 5 and Webpack, and I was able to specify the babel config in .babelrc no problem...
Thanks in advance
EDIT: The problem only occurred when running the eslint loader before the babel loader. However just updated to latest babel-loader 6.2.0 and everything is working again.
module: {
preLoaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: "eslint"}
],
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: "babel"},
{ test: /\.css$/, exclude: /node_modules/, loader: "style!css!postcss"}
It seems to be a problem with babel-loader. It should be fixed in release 6.1.0.
You can see the release/v6.1.0 summary:
* release/v6.1.0:
Update CHANGELOG.md and package.json
Set source file name relative to options.sourceRoot
Allow babelrc to be specified for cache purposes
Add BABEL_ENV || NODE_ENV to default cacheIdentifier
So updating babel-loader will suffice.

Categories

Resources