为了在Prestashop开发站点上设置HMR,我想使用browser-sync-dev-hot-webpack-plugin。
当我启动“ npm run hot”时,浏览器会启动,但是终端仍然会阻塞“ [wdm]:等到捆绑包完成:”,只要我不编辑theme.js文件即可。浏览器正在尝试无限加载图像。
一旦我修改了theme.js,WDM就会显示“编译成功”。 JS已加载到浏览器中,但是编译后的CSS不会加载到浏览器中。但是,每次编辑时它的编译情况都很好。
这是我的webpack.config.js:
const webpack = require('webpack');
const path = require('path');
const autoprefixer = require('autoprefixer');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const BrowserSyncHotPlugin = require('browser-sync-dev-hot-webpack-plugin');
const browserSyncPort = 3000;
const themeFolderName = 'classic-rocket';
const PUBLIC_PATH = `http://localhost:${browserSyncPort}/themes/${themeFolderName}/assets/js/`;
const BROWSER_SYNC_OPTIONS = {
open: true,
port: browserSyncPort,
proxy: {
target: 'server url'
},
files: [ // full page reload if .tpl file changed
'../themes/**/*.tpl',
'../modules/**/*.tpl'
]
};
const DEV_MIDDLEWARE_OPTIONS = {
publicPath: PUBLIC_PATH,
stats: {
colors: true,
chunck: false
},
hot: true
};
const HOT_MIDDLEWARE_OPTIONS = {};
module.exports = (env, argv) => {
const IS_DEV = argv.mode === "development";
const IS_PROD = argv.mode === "production";
return {
mode: argv.mode,
devtool: IS_DEV ? 'source-map' : '',
entry: {
theme: [
'./js/theme.js',
'./css/theme.scss'
]
},
output: {
path: path.resolve(__dirname, '../assets/js'),
filename: '[name].js',
publicPath: argv.hot ? PUBLIC_PATH : ""
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
include: [
path.join(__dirname, '')
],
use: ['babel-loader']
},
{
test: /\.s[ac]ss/,
use: [
{loader: MiniCssExtractPlugin.loader},
{
loader: 'css-loader',
options: {
sourceMap: IS_DEV,
minimize: IS_PROD
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: IS_DEV,
plugins: function () {
return [autoprefixer]
}
}
},
{
loader: 'sass-loader',
options: {
sourceMap: IS_DEV
}
},
]
},
{
test: /.(woff(2)?|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
exclude: [/img/],
loader: 'file-loader',
options: {
name: '../fonts/[hash].[ext]'
}
},
{
test: /\.(png|jpg|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '../img/[hash].[ext]'
}
}
]
},
{
test: /\.css$/,
use: [{
loader: 'style-loader',
options: {sourceMap: IS_DEV}
}, {
loader: 'css-loader',
options: {sourceMap: IS_DEV}
}, {
loader: 'postcss-loader',
options: {sourceMap: IS_DEV}
}]
}
]
},
externals: {
prestashop: 'prestashop',
$: '$',
jquery: 'jQuery'
},
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
test: /\.js($|\?)/i,
sourceMap: IS_DEV,
terserOptions: {
compress: {
booleans: IS_PROD,
conditionals: IS_PROD,
drop_console: IS_PROD,
drop_debugger: IS_PROD,
if_return: IS_PROD,
join_vars: IS_PROD,
keep_classnames: IS_DEV,
keep_fnames: IS_DEV,
reduce_vars: IS_PROD,
sequences: IS_PROD,
warnings: IS_DEV
},
output: {
comments: IS_DEV
}
}
}),
new OptimizeCSSAssetsPlugin({})
]
},
plugins: [
(argv.hot ?
new BrowserSyncHotPlugin({
browserSync: BROWSER_SYNC_OPTIONS,
devMiddleware: DEV_MIDDLEWARE_OPTIONS,
hotMiddleware: HOT_MIDDLEWARE_OPTIONS,
callback() {
console.log('Callback');
/*
// Use browser sync server api (https://browsersync.io/docs/api)
const { watcher: bs } = this;
bs.notify("Hello! It's callback function from BrowserSyncHotPlugin!");
*/
}
})
: false),
new MiniCssExtractPlugin({
filename: "../css/[name].css",
chunkFilename: "../css/[id].css"
}),
new webpack.ProvidePlugin({
Popper: ['popper.js', 'default']
})
].filter(function(plugin) { return plugin !== false; }),
watchOptions: {
ignored: /node_modules/
}
}
}
这是我的package.json:
{
"name": "prestarocket-dev-tools",
"version": "1.0.0",
"description": "Tools to help while developing the Classic theme",
"main": "index.js",
"scripts": {
"hot": "webpack --mode development --devtool source-map --watch --hot",
"build": "webpack -p",
"start": "webpack -p --watch",
"debug": "webpack --mode development --devtool source-map --watch",
"fulldebug": "webpack --mode development --debug --devtool source-map --output-pathinfo --display-chunks --display-error-details --watch --progress --colors"
},
"author": "Prestarocket",
"license": "AFL-3.0",
"dependencies": {
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"autoprefixer": "^9.4.4",
"babel-loader": "^8.0.4",
"bootstrap": "4.2.1",
"bootstrap-touchspin": "^4.2.5",
"browser-sync": "^2.26.3",
"css-loader": "^1.0.1",
"exports-loader": "^0.7.0",
"expose-loader": "^0.7.5",
"extract-text-webpack-plugin": "^2.1.0",
"file-loader": "^2.0.0",
"flexibility": "^2.0.1",
"imports-loader": "^0.8.0",
"jquery": "^3.3.1",
"lazysizes": "4.1.5",
"material-design-icons": "^2.1.3",
"mini-css-extract-plugin": "^0.4.5",
"node-sass": "^4.10.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"popper.js": "^1.14.6",
"postcss-flexibility": "^2.0.0",
"postcss-import": "^12.0.1",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"terser-webpack-plugin": "^1.1.0",
"webpack": "^4.26.1",
"webpack-cli": "^3.1.2",
"webpack-dev-middleware": "^3.5.1",
"webpack-hot-middleware": "^2.24.3"
},
"devDependencies": {
"browser-sync-dev-hot-webpack-plugin": "^0.2.2"
}
}
感谢您的帮助, 安东宁