webpack支持启动dev服务和热更新,并支持打包时增加文件注释
自己琢磨的一个项目,由于需要频繁的build,且需要http-server启动服务,故折腾弄了webpack的热更新服务。同时,修改配置,使支持打包时加入文件(头)注释。
准备
由于项目是基于typescript的,那我就直接按ts的来,其实差别不是很大的都是前端项目,只不过ts的解析的是ts-loader,而js则是babel-loader。
假设我们的目标文件在src目录中,新建一个index.ts,tsconfig也配置好(tsconfig配置不在本章讨论范围)。index.ts如下:
class A {
private name: string;
constructor(name: string) {
this.name = name;
}
showName() {
console.log(this.name);
}
}
export default A;
实现了一个很简单的A类并导出。 webpack.config.js内用ts-loader处理ts文件,并在dist目录下生成index.js。
const path = require('path');
module.exports = {
// 入口
entry: path.resolve(__dirname, 'src/index.ts'),
output: {
// 输出文件名
filename:'index.js',
// 输出路径
path: path.resolve(__dirname, 'dist'),
libraryExport: 'default', // 不写的话,使用时要.default
libraryTarget: 'window',
library: 'A'
},
module: {
rules: [{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}]
}
};
package.json中配置:
"start": "webpack --mode=development",
直接npm run start,我们就可以看到在dist下生成了对应的js文件了,再在根目录下创建个index.html,利用http-server就可以访问了,但是开发阶段时,我们往往会多次编译开发文件,可能会比较麻烦,所以webpack-dev-server就有他的用处了。
webpack-dev-server热更新
html-webpack-plugin
启动页面访问,最基础的就是html页面了,所以引入html打包插件。如果看webpack官方教程,这个应该是第一个接触到的插件吧。
const HtmlWebpackPlugin = require('html-webpack-plugin');
// ...
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src/index.html'),
filename: 'index.html'
})
]
// ...
先写好配置,根据配置,发现html的模板是src下的index.html页面,新增并加入基本的head,body等标签。package.json中的scripts下增加:
"dev1": "webpack-dev-server --open"
--open表示新打开浏览器,输入npm run dev1后,就可以正常出现页面了,但是遗憾的是,直接修改index.ts,不能实时更新,还得重新run dev1下。
热更新
webpack.config.js下增加contentBase表示监听的文件夹位置。
devServer: {
contentBase: './src'
}
script下增加
"dev2": "webpack-dev-server --open --watch --inline"
watch的命令来动态监听文件的改变并实时打包,实现文件修改的监听。
注:好多文章都说仅--watch只是文件的监听,不会去刷新页面,但实际测试,浏览器页面会刷新,我用的是4.29.6的webpack。 inline参数是webpack不同的刷新模式,但此处已经没有啥大用处了,所以不添加了。
到这,webpack热更新的server就搭建完成了。
注释插件
script中增加个
"build": "webpack --mode=production"
命令,npm run build后,我们得到的是一堆啥注释都没有的压缩代码。如果我们在写一些库或插件的时候,需要增加个文件注释,至少得加上版本,地址吧。此时,webpack自带的BannerPlugin插件就派上用场了。
const package = require('./package.json');
new webpack.BannerPlugin(`
${ package.name } - ${ package.description }
@version v${ package.version }
@homepage ${ package.homepage }
@author ${ package.author } <echoweb@126.com> (http://www.zhuyuntao.cn)
@license ${ package.license }
`)
我们的版本等信息往往都会存在package.json中,打包的时候就只要读取该文件就可以获取正常的信息,故我们只要该package.json里就能一遍更新了。 此时在run build,注释就可以显示了。
注:
- 待打包文件头有注释的化,是不会删掉的,还会出现在打包后的文件中。
- 其他插件有可能会删除本插件生成的注释。
区分dev与prd
如果我们只用一个wepack.config.js时,如何来区分dev下与prd下不同的插件呢?比如开发模式下,需要用到html去调试,发布时,我们只需要编译下文件就行了,这种情况下如何处理。
module.exports = (env, argv) => {
// ....
}
利用exports函数,argv.mode会返回输入命令时的mode状态,因此可以用来判断不同的模式,并返回不同的配置。
demo地址:github。
ts文件之间相互引用找不到文件的话,可以看这篇:webpack打包typescript多文件,提示没有该文件。