webpack的一些知识总结

        现在的web工程变得越来越庞大,功能变得更复杂,迭代速度也越来越快。在这种情况下,前后端分离是必然的,理应减轻后端的负担,让前端担负起更多的责任。这也给前端工程师带来了更多的技能上的要求。在这样的情形下webpack之类的工具应运而生。

        webpack非常强大,它是一个模块打包器,能帮助我们处理构建项目中繁琐的问题,如果我们能比较熟练地使用它,工作将变得轻松许多,这也是作为一个合格前端工程师必须具备的技能点。

        webpack强大但是配置起来也相当复杂,学习它应该循序渐进。根据自己项目的需求去进行学习,一蹴而就是不可能的。

          我总结下自己webpack方面的经验,希望自己能不断健全自己的知识体系,成为一名优秀的前端工程师。


一:webpack的核心概念。

          entry: 构建入口,webpack从你提供的入口开始工作,我们可以将之理解为输入。

          Module:模块,在webpack中一切皆是模块。一个模块对应一个文件。webpack会从入口开始递归找出所有依赖的模块。

          Chunk:代码块,一个Chunk由多个模块组成,用于代码的分割与合并。

          Loader:解析模块的工具,用于将模块的原始内容按照需求转换成新的内容。

          Plugin:插件,在webpack构建项目的时候,在特定的时期注入拓展逻辑。

          Output:输出结果。

构建流程:

            首先webpack从entry里配置的Module开始,递归解析entry所依赖的Module,每找到一个模块就用相应的Loader去解析,如果该模块还依赖于其他模块,那就继续解析。这些模块会以entry为单位进行分组,一个entry及其所依赖的模块就组成了一个Chunk,最后将所有Chunk转换成文件输出,在整个流程中,Webpack会在恰当是时机执行Plugin里定义的逻辑。了解它的工作流程后,当我们遇到新的需求时,就知道该去哪儿处理问题。


几个重要的内容:

     一   hash chunkhash contenthash

            hash一般是结合CDN缓存来使用的。如果文件内容发生改变,那么hash值也会改变,对应html引用的url地址也会发生改变,触发CDN服务器从原服务器上拉去相对应数据,进而跟新本地缓存。

            1. hash跟整个项目相关,只要项目里有文件更改,整个项目构建的hash值都会更改,所有文件共用相同的hash值。

            2. chunkhash:采取hash计算,每一次构建生成的hash值都不一样,即使文件内容未发生改变,这样是没办法实现缓存的,而chunkhash根据不同的入口文件区分,单独打包构建,只要我们没有改变相对应代码块的内容,那么即使项目重新构建,它也不会改变。

            3. contenthash:用于更进一步细分代码,比如一个chunk里有两个模块a,b  其中a引用了b,如果我们使用chunkhash,那么他们是作为一个chunk的,a里的代码发生改变也会导致b跟着一起重建。这时我们就可以使用contenthash将b模块单独打包。

       二: webpack-dev-server和webpack两种构建方式

            它们打包文件之间有个很重要的区别,webpack-dev-server是将文件打包到内存,我们是看不到的,所有文件都在根目录之下,webpack会把文件按照相应的配置打包到本地。

      

       三:contentBase和publicPath

            DevServer服务器通过HTTP暴露文件方式可以分为两类:

                1     暴露本地文件

                2     暴露Webpack构建出的结果,注意这里构建出的文件是在DevServer里面,本地是找不到的。

            contentBase配置DevServer HTTP服务器的文件根目录。默认情况下为当前目录。contentBase只能用来配置暴露本地文件的规则,可以通过contentBase:false来关闭暴露本地文件。

            publicPath:指定资源文件引用的目录。比如我们在开发的时候,将一些静态文件放在assets/文件夹下,但是在生产环境下,我们想把静态文件统一使用CDN加载,那该怎么办?这个时候我们就可以设置publicPath:   'http://cdnServer/xxx/' 那所有引用静态文件都会到这个地址去寻找。



常见的需求:

热更新:

                             1.在devServer中设置 hot: true

                             2.plugins中new webpack.NamedModulesPlugin()  & 

                                             new webpack.HotMdoduleReplacementPlugin()

                              注:webpack4中可以设置mode: 'development' 它会自动配置plugins


代理跨域:

                               proxy: { 'xx': {  http://xxx.xx.com/xx } } 

                  

单独提取css代码:

                                webpack4 需要最新版本的 extract-text-webpack-plugin@next

                                我们可以使用mini-css-extract-plugin:

                                plugins: new MiniCssExtractPlugin({ filename:'xxx.css', chunkFilename:'xxx.css'})


自动生成html,自动注入js,css

                     依赖于html-webpack-plugin:

                      chunks: 插入的相应的chunk,一个实例对应一个页面

new HtmlWebpackPlugin ({
filename: ' app/app.html ' ,
inject: true ,
chunks: [ ' app ' , ' commons ' , ' vendors ' , ' manifest ' ]
}),

                    


提取第三方代码&运行时代码:

           webpack4已经没有optimize.CommonsChunkPlugin改用现在的config.optimization.splitChunks和runtimeChunk.

            
optimization: {
minimize: true ,
splitChunks: {
             cacheGroups: {
                     vendors: {
                     test: / node_modules / , //来自node_modules的模块都会被分离出来
                     chunks: " all " ,
                     name: " vendors " ,
                 }
             }
},
runtimeChunk: {
name: ' manifest '                    //提取运行时代码
}
},


            提取出来后,我们还应该把他们引入回去:通过在htmlWebpackPlugin实例中chunks里设置


提取代码公共部分:

           

optimization: {
minimize: true ,
splitChunks: {
             cacheGroups: {
                 commons: {
name: ' commons ' ,
                     chunks: " initial " ,
                     minChunks: 2 ,
                     maxInitialRequests: 5 , //
                     minSize: 0 //
                 },
             }
},
},


使用动态链接库文件加快构建速度:

       1. webpack.dll.config.js

const path = require ( ' path ' )
const webpack = require ( ' webpack ' )

module . exports = {
entry: {
vendor: [ ' vue ' , ' vuex ' ]
},
output: {
filename: ' dll.[name].js ' ,
path: path . resolve ( __dirname , ' ./static ' ),
library: ' _dll_[name] '
},
plugins: [
new webpack . DllPlugin ({
context: __dirname ,
name: ' _dll_[name] ' ,
path: path . join ( __dirname , ' static ' , ' [name].manifest.json ' )
})
],
mode: ' none '
}

    

    2.webpack.base.config.js

const path = require ( ' path ' )
const webpack = require ( ' webpack ' )
const HtmlWebpackPlugin = require ( ' html-webpack-plugin ' )

module . exports = {
entry: ' ./main.js ' ,
output: {
filename: ' build.js ' ,
path: path . resolve ( __dirname , ' static ' )
},
module: {
rules: [
{
test: / \.js$ / ,
use: ' babel-loader ' ,
exclude: path . resolve ( __dirname , ' node_modules ' )
},
{
test: / \.css$ / ,
use: [ ' style-loader ' , ' css-loader?mimimize ' ]
}
]
},
plugins: [
new webpack . DllReferencePlugin ({
manifest: require ( " ./static/vendor.manifest.json " ),
}),
new HtmlWebpackPlugin ({
filename: ' index.html ' ,
template: ' ./index.html ' ,
inject: false
})
],
mode: ' none '
}

你可能感兴趣的:(webpack的一些知识总结)