webpack 5 does not accept any setting for devtool - javascript

When building with webpack 5, I get the error:
[webpack-cli] Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.devtool should match pattern "^(inline-|hidden-|eval-)?(nosources-)?(cheap-(module-)?)?source-map$".
BREAKING CHANGE since webpack 5: The devtool option is more strict.
Please strictly follow the order of the keywords in the pattern.
In my webpack.config.js however, I have the setting:
devtool: 'eval-cheap-source-map',
Ive also tried eval as value which also does not work, although this website (https://webpack.js.org/configuration/devtool/) seems to indicate that it should.
I do not understand, what is going wrong here?
edit:
my webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/app.js',
plugins: [
new HtmlWebpackPlugin({
title: 'MyApp',
}),
],
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'var',
library: 'MyApp'
},
resolve:{
alias:{
EVENTS: path.resolve(__dirname, "src/events"),
MODELS: path.resolve(__dirname, "src/models"),
GUI: path.resolve(__dirname, "src/gui"),
HELPER: path.resolve(__dirname, "src/helper")
}
},
devtool: 'eval-cheap-source-map',
devServer: {
watchContentBase: true,
contentBase: path.resolve(__dirname, 'dist'),
port: 9000
},
module: {
rules: [
{
test:/\.css$/,
use:['style-loader', 'css-loader']
}
]
},
}
my buildscript is webpack src/app.js -d --watch

Remove the -d parameter from your build script. -d stands for devtool, but it is not followed by a parameter value in your command.

Related

webpack-dev-server refuses to hot-reload html file

When using webpack-dev-server, when I make changes to the javascript file the changes are immediately reflected on the webpage.
However, when I make a change to the HTML file, the website does not reflect them. In order to see the new html page, I must first run webpack --mode production, and then, if I re-run webpack-dev-server --hot --mode development, I can see the new HTML changes.
This is quite annoying and I'd like my html changes to be hot-reloaded just like the javascript code. Is there a trick I'm missing? I've spent all day googling and playing with options. The only thing that has helped is to add
devServer:
...
devMiddleware: {
writeToDisk: true
},
to my webpack.config.js as per this answer. However, this has the following problem: My output dist/ folder gets clogged with .js files with checksum names every time a hot reload happens, which is also really annoying.
My project tree:
The full webpack.config.js:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: './src/index.ts',
watch: true,
module: {
rules: [
{
test: /\.ts?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/'
},
plugins: [
new HtmlWebpackPlugin({
title: "My app",
template: "./src/index.html",
/* This output directory is relative to the **OUTPUT** 'publicPath'!
So, if you were to write "./dist/index.html" below, it would output it in "./dist/dist/index.html"!
(You can verify this by running `npx webpack --watch` and looking what files it touches/generates.)
*/
filename: "index.html",
inject: "body"
})
],
devServer: {
// devMiddleware: { writeToDisk: true },
static: {
directory: path.join(__dirname, "dist"),
watch: true
},
compress: true,
webSocketServer: 'ws',
host: '0.0.0.0',
port: 10000,
/* Ensure I can access the server directly, without incurring the 'invalid host header' error */
allowedHosts: "all",
/* So that the webpack-dev-server reloads when I change the index.html file, even though it isn't explicitly listed anywhere. */
watchFiles: ['src/**/*'],
open: true,
hot: true,
},
};
Nevermind, I have found the issue:
Unfortunately Stackoverflow doesn't support line numbers, but if you look in the webpack.config.js code in my original question, you will find the following code:
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/'
},
That publicPath parameter appears to be what was causing the problem. Removing it made the hot-reload 'magic' autodetect that I've changed the HTML file, and re-deploy it.

webpack module function not found

I have a simple project with a few html files in root folder and a few javascript modules in scripts directory.
I want to start using webpack now because I want minification and to start using environments. Everything was working before I started using webpack.
I read documentation for Webpack 5 but could not find anything that solves my problem. So I came up with this webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry: {
lib: "./scripts/lib.js"
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
devServer: {
contentBase: "./dist",
inline: true, //Enable watch and live reload
host: "localhost",
port: 8080,
stats: "errors-only",
https: false
},
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
template: "index.html",
hash: true
})
],
module: {
rules: [
{
test: /\.html$/i,
loader: 'html-loader',
},
],
},
};
My index.html imports and uses module functions like this:
<script type="module">
import * as lib from "./scripts/lib.js";
window.lib = lib;
</script>
<body onload="lib.myFn()">
</body>
But after running this webpack (using webpack serve) I am getting "is not a function" or "module not found" errors.
How can I compile and run my existing project with webpack without making any changes in my directory structure and fix this error so I can start using functions in lib.js in my index.html? Thanks.

How to run unit test with webpack?

I have a Node Js server that I bundled with webpack with the following config:
module.exports = {
entry: './build/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
devtoolModuleFilenameTemplate: '../[resource-path]',
},
target: 'node',
node: {
__dirname: true,
},
externals: {
kcors: 'kcors',
'koa-bodyparser': 'koa-bodyparser'
},
module: {
rules: [
{
test: /\.js$/,
use: ["source-map-loader"],
enforce: "pre"
},
],
},
resolve: {
extensions: ['.js'],
},
// plugins: [
// new webpack.DefinePlugin({
// "process.env": JSON.stringify(dotenv.parsed)
// }),
// ],
devtool: 'eval-source-map'
};
This created a single file main.js inside dist
Everything looks good so far. I manually tested the server and it works.
Now, before I used webpack, I have a set of unit tests that I named with the .spec.js suffix inside my entry folder (the build/ folder) and each .js file has each own .spec file sibling located in the same directory of the .js.
To run theses unit test, I used mocha with the command: mocha build/**/*.spec.js --recursive --timeout 20000
Since I am new to webpack and the concept of bundling, how do I run the same tests from the main.js file ? I want to make sure that all tests are still passing in the bundled file
use
npm install mocha mocha-loader
config your webpack.config.js file like:
module.exports = {
entry: './entry.js',
output: {
path: __dirname,
filename: 'bundle.js',
},
module: {
rules: [
{
test: /test\.js$/,
use: 'mocha-loader',
exclude: /node_modules/,
},
],
},
};
then, call your test file from your main file like:
(into app.js)
import test from 'allMyTests';

Webpack - browser refresh on a file change which isn't module

I want to refresh page when I change (save) ./src/*.js files in my code editor.
The problem is I'm not importing this files in my entry point (with import in index.js) but I'm joining them with a plugin so code is in browser's global scope rather then in module.
Basically I want to split longer JavaScript code into smaller files, I don't want to have modules.
I've tried many configurations and closest to my needs is that below, except that it doesn't refresh browser, (it recompiles).
How can I achieve recompile and refresh on JavaScript which should be in globalscope of the browser (or all code in one module)?
webpack.config.js:
const path = require('path');
const MergeIntoSingleFilePlugin = require('webpack-merge-and-include-globally');
const FileWatcherPlugin = require("file-watcher-webpack-plugin");
module.exports = {
context: __dirname,
entry: { bundle: './src/index.js' },
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}]
},
plugins: [
new MergeIntoSingleFilePlugin({
files: {
"app.js": [
path.resolve(__dirname, './src/setup.js'),
path.resolve(__dirname, './src/buttons.js'),
path.resolve(__dirname, './src/circle.js'),
path.resolve(__dirname, './src/wall.js')
]
}
}),
new FileWatcherPlugin({
root: __dirname,
files: ['*.js']
})
],
devServer: {
contentBase: './dist',
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
hot: true,
inline: true,
// publicPath: "./src",
watchOptions: {
ignored: './node_modules/'
}
}
};
npm start:
webpack-dev-server --open --inline --hot --watch --progress
and the setup.js, buttons.js etc are regular JS script files, not exported classes.
Any ideas appreciated!

All my code runs twice when compiled by Webpack

When I build my js bundle with webpack using webpack-dev-server my code runs twice every time. Not sure how to fix it.
Screenshot of Developer Tools console
My webpack config:
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
devtool: 'cheap-eval-sourcemap',
entry: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/dev-server',
path.join(__dirname, '../src/main')
],
output: {
path: path.join(__dirname, '../dist'),
filename: 'bundle.js'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new HtmlWebpackPlugin({
template: path.join(__dirname, '../src/index.html')
}),
new CopyWebpackPlugin([
{
from: path.join(__dirname, '../assets'),
to: path.join(__dirname, '../dist/assets')
}
])
],
devServer: {
contentBase: path.join(__dirname, '../dist'),
outputPath: '/lol',
hot: true
},
module: {
loaders: [
{
test: /\.js$/,
loaders: ['babel-loader'],
include: path.join(__dirname, '../src')
}
]
}
};
in the template file you might have manually added a loading the bundle.
If you don't have the
inject: false
option in
new HtmlWebpackPlugin({
template: path.join(__dirname, '../src/index.html')
}),
the bundle will get added again.
Expanding a bit on #Emil Perhinschi's and #ggloren's earlier replies ...
Alternatively, if your ../src/index.html file does not rely on any script other than <script src="bundle.js"></script>, simply remove the latter from your index.html.
Per https://github.com/jantimon/html-webpack-plugin, the default for inject is true and ...
When passing true or 'body' all javascript resources will be
placed at the bottom of the body element.
Thus your two instantiations of bundle.js are:
The <script src="bundle.js"></script> that you (presumably) coded, and
HtmlWebpackPlugin's injection "at the bottom of the body element".

Categories

Resources