webpack4的知识总结

Posted sentangle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack4的知识总结相关的知识,希望对你有一定的参考价值。

一 环境搭建

webpack其实就是一个javascript应用程序的静态模块打包器。

webpack会将项目的资源文件当成一个一个模块,模块之间会有依赖关系,
webpack将会对这些有依赖关系的文件进行处理,让浏览器能够识别,
最后将应用程序需要的每个模块打包成一个或者多个bundle

1.安装node

node官网地址:  https://nodejs.org/zh-cn/

2.创建package.json文件

npm init

3.安装webpack

本地安装:(推荐)

npm install --save-dev webpack
npm install --save-dev webpack-cli

全局安装:

npm install --global webpack webpack-cli

4.打包

默认配置

entry:"src/index.js"
output:"dist/main.js"

package.json文件下添加scripts,配置打包模式

{
    "scripts":{
        "dev":"webpack --mode development",
        "prod":"webpack --mode production"  
    }
}

npm run dev
npm run prod

二 基础配置webpack.config.js

1.新建文件 webpack.config.js

2.配置入口entry和output

(1)path指文件打包后的存放路径
(2)path.resolve()方法将路径或路径片段的序列处理成绝对路径
(3)__dirname 表示当前文件所在的目录的绝对路径
(4)filename是打包后文件的名称

示例代码:

const path = require('path');


module.exports = {
    entry:'./public/index.js',
    output:{
        path:path.resolve(__dirname,'build'),
        filename:"bundle.js"
    }
}

示例代码2:

const path = require('path');
module.exports = {
// 多文件单出口
// entry:['./public/index.js','./public/index2.js'],
// output:{
//  path:path.resolve(__dirname,'build'),
//  filename:"bundle.js"
// }

//多入口多出口
entry:{
    pageOne: './public/pageOne/index.js',
    pageTwo: './public/pageTwo/index.js',
    pageThree: './public/pageThree/index.js'
},
output:{
    path:path.resolve(__dirname,'build'),
    filename:"[name].js"
}

}

3.配置webpack-dev-server

npm install --save-dev webpack-dev-server

配置webpack.config.js文件

devServer:{
    contentBase:"./build",
    host:"localhost",
    port:8080,
    open:true //自动打开页面
}

配置package.json

"scripts": {
    "start": "webpack-dev-server --mode development"
 }

在build文件夹下新建index.html文件,在html中引入bundle.js

npm run start

二 loader加载组件

1.加载css

npm install style-loader css-loader --save-dev

在webpack.config.js文件里配置module中的rules

module:{
    rules:[
        {
            test:/.css$/,
            use:['style-loader','css-loader']
        }
    ]
}

创建index.css文件并import进index.js文件中

import './index.css';

2.加载编译less和sass

安装less-loader和less 和 安装sass-loader和node-sass

npm install less-loader less --save-dev
npm install sass-loader node-sass --save-dev

在webpack.config.js文件里配置module中的rules

module:{
    rules:[
        {
            test:/.less$/,
            use:['style-loader','css-loader','less-loader']
        },
        {
            test:/.scss$/,
            use:['style-loader','css-loader','sass-loader']
        }
    ]
}

3.使用PostCSS添加浏览器前缀

npm install --save-dev  postcss-loader autoprefixer

需要和autoprefixer一起用,在webpack.config.js文件里配置module中的rules

module:{
    rules:[
        {
            test:/.css$/,
            use:['style-loader','css-loader',{
                loader:'postcss-loader',
                options:{
                    plugins:[require("autoprefixer")()]
                }
            }]
        }
    ]
}

4 文件处理

npm install --save-dev file-loader

图片module中的rules

module:{
    rules:[
        {
            test:/.(png|jpg|gif|jpeg)$/,
            use:[{
                loader:'file-loader',
                options:{
                    name:'[hash]wangou.jpg',
                    outputPath:'./img'
                }
            }]
        }
    ]
}
         

配置options:

name:为你的文件配置自定义文件名模板(默认值[hash].[ext])
context:配置自定义文件的上下文,默认为 webpack.config.js
publicPath:为你的文件配置自定义 public 发布目录
outputPath:为你的文件配置自定义 output 输出目录

[ext]:资源扩展名
[name]:资源的基本名称
[path]:资源相对于 context的路径
[hash]:内容的哈希值
                

字体module中的rules

module:{
    rules:[
        {
            test:/.(ttf|woff|woff2|eot|svg)$/,
            use:[{
                loader:'file-loader',
                options:{
                    outputPath:'font/'
                }
            }]
        }
    ]
}

js库module中的rules

     以jquery库为例子

1)本地导入

const webpack = require('webpack');

module.exports = {
    entry:'./public/index.js',
    
    resolve:{
        alias:{
            jQuery: path.resolve(__dirname,"public/js/jquery.min.js")
        }
    },
    plugins:[
        new webpack.ProvidePlugin({
            jQuery:"jQuery"
        })
    ]
}
                

2)npm安装模块

安装jquery库:

npm install jquery --save-dev

直接在js里import引入

import $ from 'jquery'

5 HTML中引入图片

cnpm install --save-dev html-loader

module中的rules

{
    test:/.(html)$/,
    option:{
        attrs:['img:src', 'img:data-src']
    }
}

6.babel编译ES6

module:{
        rules:[
            {
                test:/.js$/,
                exclude:/node_modules/,
                use:'babel-loader'
            }
        ]
    },

webpack 插件

1.生成HTML

npm install html-webpack-plugin --save-dev

module中的rules

const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins:[

    new HtmlWebpackPlugin({
        template:"./public/index.html",
        filename:"webpack.html",
        minify:{
            minimize:true,
            removeComments:true,
            removeAttributeQuotes:true,
            collapseWhitespace:true,
            minifyCSS:true,
            minifyJS:true,
            removeEmptyElements:true
        },
        hash:true
    })
]

2.提取分离css

npm install --save-dev mini-css-extract-plugin

module中的rules

const MiniCssExtractPlugin =  require("mini-css-extract-plugin")
module:{
    rules:[
        
        {
            test:/.css$/,
            use:[MiniCssExtractPlugin.loader,'css-loader',{
                loader:'postcss-loader',
                options:{
                    plugins:[require("autoprefixer")()]
                }
            }]
        }
    ]
},

plugins:[
    new MiniCssExtractPlugin({
        filename:"./css/[name].css"
    })
]

3 压缩css及优化css结构

npm install --save-dev optimize-css-assets-webpack-plugin

module中的rules

const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

plugins:[   
    new OptimizeCSSAssetsPlugin({
        assetNameRegExp:/.css$/g,
        cssProcessor:require('cssnano'),
        cssProcessorPluginOptions:{
            preset:['default',{discardComments:{removeAll:true}}]
        },
        canPrint:true
    })
]

4copy静态文件

module中的rules

const CopyWebpackPlugin = require('copy-webpack-plugin');

plugins:[
    new CopyWebpackPlugin([
        {
            from:__dirname+'/public/assets',
            to:__dirname+'/build/assets'
        }
    ])
]

5清除垃圾文件

npm install --save-dev clean-webpack-plugin

module中的rules

const CleanWebpackPlugin = require('clean-webpack-plugin');

plugins:[
    new CleanWebpackPlugin({
        dry: false
    }),
]

6 SourceMap 调试代码

1)js调试

devtool:"source-map"

2)css调试

调试css时需要将压缩css的插件注释掉(optimize-css-assets-webpack-plugin)

module:{
    rules:[
        {
            test:/.css$/,
            use:[{
                loader:'css-loader',
                options:{
                    source:true
                }
            }]
        }
    ]
},

7模块热替换

devServer:{
    contentBase:'./build',  //设置服务器访问的基本目录
    host:'localhost', //服务器的ip地址
    port:8080,  //端口
    open:true,  //自动打开页面
    hot:true,
    hotOnly:true
},
plugins:[
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin(),
]

entry文件js

if(module.hot){
    module.hot.accept()
}

8区分生产环境和开发环境

npm install --save-dev webpack-merge

将webpack.config.js拆分为三个文件,分别是webpack.common.conf.js、webpack.dev.conf.js和webpack.prod.conf.js。
webpack.common.conf.js是放一些我们公用的配置,比如入口entry、出口output、常用loader以及插件等。
webpack.dev.conf.js是在开发环境上的配置,比如devServer配置、模块热替换等方便开发的配置
webpack.prod.conf.js是在生产环境上的配置,比如提取分离css、压缩css和js等

webpack.common.conf.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
    entry:'./public/index.js',
    output:{
        path:path.resolve(__dirname,'../build'),
        filename:"bundle.js"
    },
    module:{
        rules:[
            {
                test:/.css$/,
                use:['style-loader','css-loader',{
                    loader:'postcss-loader',
                    options:{
                        plugins:[require("autoprefixer")()],
                        sourceMap:true
                    }
                }]
            },
            {
                test:/.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            {
                test:/.scss$/,
                use:['style-loader','css-loader','sass-loader']
            },
            {
                test:/.(png|jpg|gif|jpeg)$/,
                use:[{
                    loader:'file-loader',
                    options:{
                        name:'[hash]wangou.jpg',
                        outputPath:'./img'
                    }
                }]
            },
            {
                test:/.(ttf|woff|woff2|eot|svg)$/,
                use:[{
                    loader:'file-loader',
                    options:{
                        outputPath:'font/'
                    }
                }]
            },
            {
                test:/.js$/,
                exclude:/node_modules/,
                use:'babel-loader'
            },
            {
                test:/.(html)$/,
                use:{
                    loader:'html-loader',
                    options: {
                        attrs: ['img:src','img:data-src']
                    }
                }
            }
        ]
    },
    resolve:{
        alias:{
            jQuery: path.resolve(__dirname,"../public/js/jquery.min.js")
        }
    },
    plugins:[
        new CleanWebpackPlugin(['build'],{
            root:path.resolve(__dirname,'../')
        }),
        new webpack.ProvidePlugin({
            jQuery:"jQuery"
        }),
        new HtmlWebpackPlugin({
            template:"./public/index.html",
            filename:"webpack.html",
            minify:{
                minimize:true,
                removeComments:true,
                removeAttributeQuotes:true,
                collapseWhitespace:true,
                minifyCSS:true,
                minifyJS:true,
                removeEmptyElements:true
            },
            hash:true
        }),
        // 分离css
        // new ExtractTextPlugin("./css/[name].css")
        new MiniCssExtractPlugin({
            filename:"./css/[name].css"
        }),
    ]
}

webpack.dev.conf.js

const webpack = require('webpack');
const merge = require('webpack-merge');
const common = require('./webpack.common.conf.js');
module.exports = merge(common,{
    devtool:'cheap-module-eval-source-map',
    devServer:{
        contentBase:'./build',  //设置服务器访问的基本目录
        host:'localhost', //服务器的ip地址
        port:8080,  //端口
        open:true,  //自动打开页面
        hot:true,
        hotOnly:true
    },
    plugins:[
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()
    ]
}) 

webpack.prod.conf.js

const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const common = require('./webpack.common.conf.js');
const merge = require('webpack-merge');
const path = require('path');

module.exports = merge(common,{
    devtool:'source-map',
    plugins:[
        new CopyWebpackPlugin([
                {
                    from:path.resolve(__dirname,'../public/assets'),
                    to:path.resolve(__dirname,'../build/assets')
                }
        ])
    ]
})

配置文件package.json

"scripts": {
    "dev": "webpack --mode development --config ./config/webpack.dev.conf.js",
    "build": "webpack --mode production --config ./config/webpack.prod.conf.js",
    "start": "webpack-dev-server --mode development --config ./config/webpack.dev.conf.js"
},

四 优化打包的速度

1.减少文件搜索范围

1)优化resolve.extensions配置

在导入语句没带文件后缀时,Webpack 会自动带上后缀后去尝试询问文件是否存在。

在配置 resolve.extensions 时你需要遵守以下几点,以做到尽可能的优化构建性能:

?   后缀尝试列表要尽可能的小,不要把项目中不可能存在的情况写到后缀尝试列表中。
?   频率出现最高的文件后缀要优先放在最前面,以做到尽快的退出寻找过程。
?   在源码中写导入语句时,要尽可能的带上后缀,从而可以避免寻找过程。例如在你确定的情况下把 require('./data') 写成 require('./data.json') 。

2)优化 resolve.modules 配置

resolve.modules 用于配置 Webpack 去哪些目录下寻找第三方模块。
resolve.modules 的默认值是 [‘node_modules‘],会采用向上递归搜索的方式查找

(3)优化resolve.alias配置

resolve.alias 配置项通过别名来把原导入路径映射成一个新的导入路径。

(4)缩小文件匹配范围

Include:需要处理的文件的位置
Exclude:排除掉不需要处理的文件的位置

2.设置noParse

防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中不应该含有 import, require, define 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。比如jquery、elementUI等库

3.给babel-loader设置缓存

babel-loader 提供了 cacheDirectory特定选项(默认 false):设置时,给定的目录将用于缓存加载器的结果。

4.使用happyPack

HappyPack的基本原理:在webpack构建过程中,我们需要使用Loader对js,css,图片,字体等文件做转换操作,并且转换的文件数据量也是非常大的,且这些转换操作不能并发处理文件,而是需要一个个文件进行处理,HappyPack的基本原理是将这部分任务分解到多个子进程中去并行处理,子进程处理完成后把结果发送到主进程中,从而减少总的构建时间。

以上是关于webpack4的知识总结的主要内容,如果未能解决你的问题,请参考以下文章

线程学习知识点总结

webpack4知识汇总

webpack4知识汇总2

关于webpack4的14个知识点,童叟无欺

webpack4之踩坑总结

从基础到实战 手把手带你掌握新版Webpack4.0