如果你喜欢这系列的文章,欢迎star
我的项目,源码地址,点击这里
优化项
-
开发调试所用的
sourcemap
-
js
文件增加hash
值,方便缓存 -
配置模块热更新
增加 sourcemap
开发过程中,代码出错是难免的,那么调试就很重要了,webpack
帮我们打包所有文件,省了我们很多事情,但打包后的代码,却不适合用来调试,可以通过在 webpack
中增加 devtool
配置,来向浏览器暴露我们的源码,让我们可以在源码的基础上,进行调试
在 webpack.dev.conf.js
中,增加如下配置:
// 开发工具
devtool: 'eval-source-map',
这样代码哪里错了,可以看到是在源码的哪里,而不会因为编译后报错,却找不到具体是哪里出错
devtool
有很多种值可选,这里只是其中的一种,可自行百度了解~
增加缓存机制
此前,我们的出口文件 bundle.js
是一个固定的名字,如果项目上线后,用户缓存了该文件,而后期我们修改了文件,用户却已经缓存过该文件,从而无法获取最新,这时候,我们就需要通过 hash
值来确保,只要文件更新了,hash
值发生变化,文件名就会不同,用户会缓存新的文件,从而达到获取最新
那么这里就需要修改 webpack.dev.conf.js
文件的出口配置了:
// 输出文件配置项
output:{
path:path.resolve(__dirname,"dist"),
filename: 'js/[name].[hash].js',
chunkFilename: 'js/[name].[chunkhash].js',
publicPath:""
},
执行命令 npm start
查看效果,页面能正常显示,打开开发者工具,可发现,引入的 js
文件,已经不叫 bundle.js
了,而变成了 main
开头加一段 hash
值的一个文件,这个 main
是 webpack
默认的出口文件名,要想这里也可控,只需修改入口文件配置即可
// 入口文件配置项
entry:{
app:[path.resolve(__dirname, 'src/index.js')],
},
再执行命令 npm start
查看效果,是不是已经变成了我们设置的 app
这个名字?~
增加模块热更新
现阶段我们每次修改页面,页面都会自动整体刷新,但是现在不想刷新整个页面,而是改了哪里,就刷新哪里
需要修改 webpack.dev.conf.js
文件的 plugins
以及 devServer
的配置
// 插件配置项
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',//输出文件的名称
template: path.resolve(__dirname, 'src/index.html'),//模板文件的路径
title:'webpack-主页',//配置生成页面的标题
}),
new webpack.HotModuleReplacementPlugin()
],
// 开发服务配置项
devServer: {
port: 8080,
contentBase: path.resolve(__dirname, 'dist'),
historyApiFallback: true,
host: ip,
overlay:true,
hot:true,
inline:true,
after(){
open(`http://${ip}:${this.port}`)
.then(() => {
console.log(chalk.cyan(`http://${ip}:${this.port} 已成功打开`));
})
.catch(err => {
console.log(chalk.red(err));
});
}
}
上面我们在 plugins
配置中引用了一个插件,这个插件是依托的 webpack
所以我们需要在文件头部引入 webpack
const webpack = require("webpack");
接下来,我们还需要修改 src/index.js
文件,当局部模块更新时,通知该文件
import './css/reset.css';
import './scss/public.scss';
import './less/index.less';
import image from './images/favicon.png';
if (module.hot) {
module.hot.accept();
}
var func = str => {
document.getElementById('app').innerHTML = str;
};
func('我现在在使用 es6 新语法-箭头函数!');
document.getElementById('postcss').innerHTML = "<h1>我自动添加了浏览器前缀</h1><img src='"+ image +"'/><span class='icon iconfont icon-toPay'></span>";
增加的代码为:
if (module.hot) {
module.hot.accept();
}
这段代码需要放在引入下面,页面代码上面~
到此模块热更新算是初步配置完成了,现在执行命令 npm start
然后修改样式,或者入口文件内编译的内容,看看浏览器,已经不会去刷新整个页面了,而是哪里涉及到修改,就刷新哪里
相关文件配置信息更新情况
以下为本文已涉及到的配置文件的当前详细信息
webpack.dev.conf.js
文件现在的配置信息情况:
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const open = require('opn');//打开浏览器
const chalk = require('chalk');// 改变命令行中输出日志颜色插件
const ip = require('ip').address();
module.exports = {
// 入口文件配置项
entry:{
app:[path.resolve(__dirname, 'src/index.js')],
},
// 输出文件配置项
output:{
path:path.resolve(__dirname,"dist"),
filename: 'js/[name].[hash].js',
chunkFilename: 'js/[name].[chunkhash].js',
publicPath:""
},
// 开发工具
devtool: 'eval-source-map',
// webpack4.x 环境配置项
mode:"development",
// 加载器 loader 配置项
module:{
rules:[
{
test: /\.css$/,
use: [{
loader: 'style-loader'
},{
loader: 'css-loader'
},{
loader: 'postcss-loader',
options: {
sourceMap: true,
config: {
path: 'postcss.config.js'
}
}
}
]
},
{
test: /\.scss$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
config: {
path: 'postcss.config.js'
}
}
},
{
loader: 'sass-loader',
options: { sourceMap: true }
}
],
exclude: /node_modules/
},
{
test: /\.less$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
importLoaders: 1,
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
config: {
path: 'postcss.config.js'
}
}
},
{
loader: 'less-loader',
options: {
sourceMap: true,
}
}
]
},
{
test: /\.(png|jp?g|gif|svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // 小于8192字节的图片打包成base 64图片
name:'images/[name].[hash:8].[ext]',
publicPath:''
}
}
]
},
{
// 文件依赖配置项——字体图标
test: /\.(woff|woff2|svg|eot|ttf)$/,
use: [{
loader: 'file-loader',
options: {
limit: 8192,
name: 'fonts/[name].[ext]?[hash:8]',
publicPath:''
},
}],
}, {
// 文件依赖配置项——音频
test: /\.(wav|mp3|ogg)?$/,
use: [{
loader: 'file-loader',
options: {
limit: 8192,
name: 'audios/[name].[ext]?[hash:8]',
publicPath:''
},
}],
}, {
// 文件依赖配置项——视频
test: /\.(ogg|mpeg4|webm)?$/,
use: [{
loader: 'file-loader',
options: {
limit: 8192,
name: 'videos/[name].[ext]?[hash:8]',
publicPath:''
},
}],
}, {
test:/\.html$/,
use:[
{
loader:"html-loader",
options:{
attrs:["img:src","img:data-src"]
}
}
]
}
]
},
// 插件配置项
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',//输出文件的名称
template: path.resolve(__dirname, 'src/index.html'),//模板文件的路径
title:'webpack-主页',//配置生成页面的标题
}),
new webpack.HotModuleReplacementPlugin()
],
// 开发服务配置项
devServer: {
port: 8080,
contentBase: path.resolve(__dirname, 'dist'),
historyApiFallback: true,
host: ip,
overlay:true,
hot:true,
inline:true,
after(){
open(`http://${ip}:${this.port}`)
.then(() => {
console.log(chalk.cyan(`http://${ip}:${this.port} 已成功打开`));
})
.catch(err => {
console.log(chalk.red(err));
});
}
}
}