1、webpack是什么
根据文档的定义:本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
2、webpack四个核心概念
- 入口(entry) 入口,webpack 执行构建的第一步将从 Entry 开始,可抽象成输入
- 输出(output) 输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果
- 加载器(loader) 模块转换器,用于把模块原内容按照需求转换成新内容。
- 插件(plugins) 扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。
2.1entry
- 定义的三种方法
第一种用法
module.exports = {
entry:'index.js'
}
第二种用法
module.exports = {
entry:['index.js','b.js']
}
第三种用法
module.exports = {
entry:{
index:'index.js',
b:'b.js'
}
}
推荐使用使用第三种方法,方便分清各个入口的定义
2.2output
- 打包成的文件
- 一个或多个
module.exports = {
entry:{
index:'index.js',
b:'b.js'
},
output:{
path:path.resolve(__dirname,'dist'),
filename:'[name].min.[hash:5].js'
}
}
在上面的例子中,
- output中的name和entry中的key相对应
- output的filename可以指定hash。有两个值可以选择:
- [hash]:hash值是特定于整个构建过程的。
- [chunkhash]:hash值是特定于每一个文件的内容的。
我们理想的缓存设计是,在一次版本更新(重新构建)后,只有当一个文件的内容确实发生了变化,它才需要被重新下载,否则应使用缓存。 因此,以上两个值中更推荐的是[chunkhash]。你也可以阅读这篇官方的缓存指南了解更多细节。
2.3loader
- 作用: 通过使用不同的Loader,Webpack可以要把不同的文件都转成JS文件,比如CSS、ES6/7、JSX等
- 参数
- test:匹配处理文件的扩展名的正则表达式
- use:loader名称,就是你要使用模块的名称
- include/exclude:手动指定必须处理的文件夹或屏蔽不需要处理的文件夹
- query:为loaders提供额外的设置选项 下面以css-loader为例
module: {
+ rules:[
+ {
+ test:/\.css$/,
+ use:['style-loader','css-loader'],
+ include:path.join(__dirname,'./src'),
+ exclude:/node_modules/
+ }
+ ]
},
- 常用的loader
- 编译相关
babel-loader ts-loader - 样式相关 style-loader css-loader less-loader postcss-loader
- 文件相关 file-loader url-loader
- 编译相关
2.4plugins
- 参与打包的整个过程
- 打包优化和压缩
- 配置编译时的变量
- 用法(以压缩js插件为例)
module.exports = {
plugins: [
new UglifyjsWebpackPlugin()
]
}
- 常用的plugin
- 优化相关
- CommonsChunkPlugin
- UglifyjsWebpackPlugin
- 功能相关
- ExtractTextWebpackPlugin
- HtmlWebpackPlugin
- HotModuleReplacementPlugin
- CopyWebpackPlugin
- 优化相关
3、wbpack的常用配置
3.1配置开发服务器
npm i webpack-dev-server -D
+ devServer:{
+ contentBase:path.resolve(__dirname,'dist'),
+ host:'localhost',
+ compress:true,
+ port:8080
+ }
- contentBase 配置开发服务运行时的文件根目录
- host:开发服务器监听的主机地址
- compress 开发服务器是否启动gzip等压缩
- port:开发服务器监听的端口
3.2自动产出html
npm i html-webpack-plugin -D
plugins: [
+ new HtmlWebpackPlugin({
+ minify: {
+ removeAttributeQuotes:true
+ },
+ hash: true,
+ template: './src/index.html',
+ filename:'index.html'
})]
- minify 是对html文件进行压缩,removeAttrubuteQuotes是去掉属性的双引号
- hash 引入产出资源的时候加上哈希避免缓存
- template 模版路径
3.3分离css
因为CSS的下载和JS可以并行,当一个html文件很大的时候,我们可以把css单独提取出来
npm install --save-dev extract-text-webpack-plugin
module: {
+ rules:[
+ {
+ test:/\.css$/,
+ use: ExtractTextWebpackPlugin.extract({
+ use:'css-loader'
+ }),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
+ }
+ ]
},
plugins: [
+ new ExtractTextWebpackPlugin('css/index.css')]
3.4编译less 和 sass
npm i less less-loader -D
npm i node-saas sass-loader -D
const cssExtract=new ExtractTextWebpackPlugin('css.css');
const lessExtract=new ExtractTextWebpackPlugin('less.css');
const sassExtract=new ExtractTextWebpackPlugin('sass.css');
{
test:/\.less$/,
use: lessExtract.extract({
use:['css-loader','less-loader']
}),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},
{
test:/\.scss$/,
use: sassExtract.extract({
use:['css-loader','sass-loader']
}),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},
3.5处理CSS3属性前缀
为了浏览器的兼容性,有时候我们必须加入-webkit,-ms,-o,-moz这些前缀
-
Trident内核:主要代表为IE浏览器, 前缀为-ms
-
Gecko内核:主要代表为Firefox, 前缀为-moz
-
Presto内核:主要代表为Opera, 前缀为-o
-
Webkit内核:产要代表为Chrome和Safari, 前缀为-webkit
npm i postcss-loader autoprefixer -D
module.exports={
plugins:[require('autoprefixer')]
}
{
test:/\.css$/,
use: cssExtract.extract({
+ use:['css-loader','postcss-loader']
}),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},
postcss-loader其它用法可以参考文档
3.6转义ES6/ES7
Babel其实是一个编译JavaScript的平台,可以把ES6/ES7,React的JSX转义为ES5
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 babel-preset-react -D
{
test:/\.jsx?$/,
use: {
loader: 'babel-loader',
options: {
presets: ["env","stage-0","react"]
}
},
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},
3.7调试打包后的代码
webapck通过配置可以自动给我们sourcemaps文件,map文件是一种对应编译文件和源文件的方法
- source-map 把映射文件生成到单独的文件,最完整最慢
- cheap-module-source-map 在一个单独的文件中产生一个不带列映射的Map
- eval-source-map 使用eval打包源文件模块,在同一个文件中生成完整sourcemap
- cheap-module-eval-source-map sourcemap和打包后的JS同行显示,没有映射列
module.exports = {
devtool:'eval-source-map'
}
3.8watch
当代码发生修改后可以自动重新编译
new webpack.BannerPlugin(''),
watch: true,
watchOptions: {
ignored: /node_modules/, //忽略不用监听变更的目录
aggregateTimeout: 500, //防止重复保存频繁重新编译,500毫米内重复保存不打包
poll:1000 //每秒询问的文件变更的次数
},
3.9拷贝静态文件
有时项目中没有引用的文件也需要打包到目标目录
npm i copy-webpack-plugin -D
new CopyWebpackPlugin([{
from: path.join(__dirname,'public'),//静态资源目录源地址
to:'./public' //目标地址,相对于output的path目录
}]),
3.10打包先清空
npm i clean-webpack-plugin -D
new cleanWebpaclPlugin(path.join(__dirname,'dist'))
3.11压缩js /css
-
压缩JS可以让输出的JS文件体积更小、加载更快、流量更省,还有混淆代码的加密功能 npm i uglifyjs-webpack-plugin -D plugins: [ new UglifyjsWebpackPlugin(),
-
webpack可以消除未使用的CSS,比如bootstrap中那些未使用的样式
npm i -D purifycss-webpack purify-css npm i bootstrap -S
{
test:/\.css$/,
use: cssExtract.extract({
use: [{
loader: 'css-loader',
+ options:{minimize:true}
},'postcss-loader']
}),
},
+ new PurifyCSSPlugin({
+ //purifycss根据这个路径配置遍历你的HTML文件,查找你使用的CSS
+ paths:glob.sync(path.join(__dirname,'src/*.html'))
+ }),
4、总结
以上是webpack核心概念总结,对概念的理解,有助于总体了解下webpack不同的作用,遇到相关问题,找对应的模块。