webpack配置总结

1.创建webpack环境:这里是局部安装,只限于本项目。

(1)mkdir studyReact
  (2)cd studyReact
  (3)npm init
        package name:webpack-get-started
        license:MIT
     生成package.json
  (4)npm install webpack webpack-cli -D
  (5)如果想要在项目中使用npm run build命令,
        ①配置
        "scripts":{
            "build":"webpack --mode production"
        }
        ②新建src目录,在目录下新建index.js
        ③执行npm run build会在根目录下生成dist目录,目录中有main.js文件
        注:如果使用的是"webpack --mode development"打包之后的代码不会被压缩

2.配置更多webpack,需要在根目录新建webpack.config.js文件(不要问为什么取这个名字,现在知道这个名字就行啦,会自动读取内容配置webpack)

const path = require('path');
   module.exports = {
       entry: './src/index.js',      // 文件入口
       output: {                     // 文件出口
           path: path.resolve(__dirname,'dist2'), // 文件出口目录路径
           filename:'index.js',                  // 文件出口文件名
       }
   }
   ①配置多文件入口
       entry: {
            main:'./src/main.js',
            index: './src/index.js',
       }
       结果:会在dist目录下生成main.js和index.js文件
       注意:如果多入口单出口就会报错,所以此时的output应该配置为
            output: {                     // 文件出口
               path: path.resolve(__dirname,'dist2'), // 文件出口目录路径
               filename:'[name].js',                  // 文件出口文件名
           }
           或者
           output: {                     // 文件出口
              path: path.resolve(__dirname,'dist2'), // 文件出口目录路径
          }

   ②为filename添加hash值
            output: {                     // 文件出口
               path: path.resolve(__dirname,'dist2'), // 文件出口目录路径
               filename:'[name].[hash].js',           // 文件出口文件名
           }
            结果:会在dist2目录下生成类似于  home.0f83e169b1d1e4e2260b.js文件
            弊端:此hash值会作用于整个webpack,一个文件的修改会让整个目录下的hash值修改。
                 如果要让每个文件的hash值不一样,使用chunkHash
            注意:
                output: {                     // 文件出口
                   path: path.resolve(__dirname,'dist2'), // 文件出口目录路径
                   filename:'[name].[hash:6].js',          // 文件出口文件名
               }
               结果:hash值会被截断
   ③指定webpack.config.js目录
        在package.json中配置
            "scripts": {
                "build":"webpack --mode production --config scripts/webpack.config.prod.js",
              },

2.配置一个基础开发环境

 ①让webpack自身生成html文件,无需手动生成
            第一步:npm install --save-dev html-webpack-plugin
            第二步:配置webpack.config.js
                    const path = require('path');
                    const HtmlWebpackPlugin = require('html-webpack-plugin');

                    module.exports = {
                        entry: './src/index.js',      // 文件入口
                        output: {                     // 文件出口
                            path: path.resolve(__dirname,'dist'), // 文件出口目录路径
                            filename:"[name].[hash:8].js",           // 文件出口文件名
                        },
                        plugins:[
                            new HtmlWebpackPlugin()
                        ]
                    }
                  执行 npm run build会在dist目录下生成index.html文件
                  注意:如果要指定index.html文件应该怎么办?
                        第一步:在根目录下创建index.html文件
                              注意:html文件的title标签内容应该修改为
                                    <title><%= htmlWebpackPlugin.options.title %></title>
                                   这样title才会是HtmlWebpackPlugin中配置的title
                        第二步:配置
                                plugins:[
                                    new HtmlWebpackPlugin({
                                        title:'webpack',
                                        template:'./src/index.html',
                                        filename:'index.html',
                                        minify:{         // 压缩html文件
                                            removeAttributeQuotes: true,  // 删除双引号
                                            collapseInlineTagWhitespace: true,  //压缩变成一行
                                        },
                                        hash: true,     // 引用js文件添加hash值
                                    })
                                ]
        ②让webpack编译css文件
            第一步:npm install --save-dev css-loader
                   npm install style-loader -D
            第二步:配置webpack.config.js
                    module:{
                        rules:[
                            {
                                test:/\.css$/,
                                use:[
                                    'style-loader',   // 主要解析@import语法
                                    'css-loader'      // 把css插入到head标签中
                                ]
                            }
                        ]
                    },
                   结果:执行npm run build会生成.html和.js文件
                   问:如何生成独立的css文件,让html文件link引入
                        第一步:npm install --save-dev mini-css-extract-plugin
                        第二步:
                              const MinCssExtractPlugin = require('mini-css-extract-plugin');  // 生成独立的css文件
                              plugins:[
                                  new HtmlWebpackPlugin({
                                      title:'webpack',
                                      template:'index.html'
                                  }),
                                  new MinCssExtractPlugin({
                                      filename:'[name].css'
                                  }),
                              ]
                              修改
                                rules:[
                                    {
                                        test:/\.css$/,
                                        use:[
                                            'style-loader',
                                            'css-loader'
                                        ]
                                    }
                                ]
                                为:
                                rules:[
                                    {
                                        test:/\.css$/,
                                        use:[
                                            MinCssExtractPlugin.loader,
                                            'css-loader'
                                        ]
                                    }
                                ]

            问:如果让写在html文件中的样式起作用怎么办?    
                module:{
                    rules:[
                        {
                            test:/\.css$/,
                            use:[
                                {                 // 主要解析@import语法
                                    loader:'style-loader',
                                    options:{
                                        insert:'top'    // 插入到header标签中的最上面
                                    }
                                },   
                                'css-loader'      // 把css插入到head标签中
                            ]
                        }
                    ]
                },              

        ③启动一个开发服务器,同时实现热加载
            npm install webpack-dev-server --save-dev
            在package.json中添加
                "scripts": {
                    "build": "webpack --mode production",
                    "dev": "webpack-dev-server --mode development",
                  },
            执行npm run dev
            在浏览器中输入http://localhost:8080/ 访问
            问:如何配置端口相关的信息?
                在webpack.config.js中配置
                devServer:{
                    port: 3000,  // 端口
                    open: true,  // 自动打开浏览器
                    progress: true, // 显示进度
                    contentBase: './dist', // 打包之后的只是文件夹,这个属性帮助找到index.html文件
                    compress: true,
                }

3.配置css预处理(less scss)

①如何处理less
    第一步:npm install less-loader less --save-dev
    第二步:在webpack.config.js中配置
            rules:[
                {
                    test:/\.css$/,
                    use:[
                        MinCssExtractPlugin.loader,
                        'css-loader'
                    ]
                },
                {
                    test:/\.less$/,
                    use:[
                        MinCssExtractPlugin.loader,
                        'css-loader',
                        'less-loader'
                    ]
                }
            ],
            问:如果css需要使用某些特定的前缀怎么办,如::placeholder{color: red;}
                第一步:npm install postcss-loader autoprefixer -D
                       [npm i -D postcss-load-config
                       npm install cosmiconfig]  我的电脑需要安装这两个
                第二步:配置webpack.config.js
                        rules:[
                            {
                                test:/\.css$/,
                                use:[
                                    MinCssExtractPlugin.loader,
                                    'css-loader',
                                    'postcss-loader',
                                ]
                            },
                            {
                                test:/\.less$/,
                                use:[
                                    MinCssExtractPlugin.loader,
                                    'css-loader',
                                    'postcss-loader',
                                    {
                                        loader:'less-loader',
                                        options:{

                                        }
                                    },
                                ]
                            }
                        ],
                第三步:在根目录下新建postcss.config.js
                    内容为:
                        module.exports={
                            plugins:[
                                require('autoprefixer')
                            ]
                        }
                第四步,在package.json中配置
                    "browserslist": [
                        "cover 99.5%"
                      ]
②如何处理scss?
    第一步:npm install node-sass sass-loader --save-dev
    第二步:在webpack.config.js中配置
            rules:[
                {
                    test:/\.css$/,
                    use:[
                        MinCssExtractPlugin.loader,
                        'css-loader',
                        'postcss-loader',
                    ]
                },
                {
                    test:/\.less$/,
                    use:[
                        MinCssExtractPlugin.loader,
                        'css-loader',
                        'postcss-loader',
                        {
                            loader:'less-loader',
                            options:{

                            }
                        },
                    ]
                },
                {
                    test:/\.scss$/,
                    use:[
                        MinCssExtractPlugin.loader,
                        'css-loader',
                        'postcss-loader',
                        {
                            loader:'sass-loader',
                            options:{

                            }
                        },
                    ]
                }
            ],
③如何压缩css文件
    第一步:npm install optimize-css-assets-webpack-plugin --save-dev
           npm install uglifyjs-webpack-plugin --save-dev
    第二步:配置webpack.config.js
            module.exports = {
                optimization:{       // 优化项
                    minimizer:[
                        new UglifyjsWebpackPlugin(   // 压缩js
                            {
                                cache: true,
                                parallel: true,
                                sourceMap: true
                            }
                        ),
                        new OptimizeCssAssetsWebpackPlugin() // 压缩css
                    ]
                }
            }

4.处理图片文件

第一步:npm install file-loader --save-dev
      npm install url-loader --save-dev
第二步:在webpack.config.js中配置
    rules:[
        {
            test:/\.css$/,
            use:[
                MinCssExtractPlugin.loader,
                'css-loader',
                'postcss-loader',
            ]
        },
        {
            test:/\.less$/,
            use:[
                MinCssExtractPlugin.loader,
                'css-loader',
                'postcss-loader',
                {
                    loader:'less-loader',
                    options:{

                    }
                },
            ]
        },
        {
            test:/\.scss$/,
            use:[
                MinCssExtractPlugin.loader,
                'css-loader',
                'postcss-loader',
                {
                    loader:'sass-loader',
                    options:{

                    }
                },
            ]
        },
        {
            test: /\.(png|jpe?g|gif)$/i,
            use: [
                {
                    loader: 'file-loader',
                    options:{
                        name:'static/images/[name].[ext]',
                        publicPath:'/',
                    }
                },
                或者:
                {
                    loader: 'url-loader',
                    options:{
                        limit:512,
                        name:'static/images/[name].[ext]',
                        publicPath:'/',
                    }
                },
            ],
        },
    ],
问:如果要在index.html文件中引入图片怎么办?
    第一步:npm install html-withimg-loader --save-dev
    第二步:在webpack.config.js中配置   
            {
                test: /\.(png|jpe?g|gif)$/i,
                use:{
                    loader:'file-loader',
                    options: {
                        esModule: false,     //非常重要
                    },
                }
            },
            {
                test: /\.html$/,
                use:{
                    loader:'html-withimg-loader'
                },
            }

5.处理静态文件,如字体图标,无需编译直接复制即可

第一步:npm install copy-webpack-plugin --save-dev
第二步:
    const CopyPlugin = require('copy-webpack-plugin');
    在webpack.config.js中配置
        plugins:[
            new CopyPlugin([
                {
                    from: path.resolve(process.cwd(),'src/static/'),
                    to: path.resolve(process.cwd(),'dist/static/')
                }
            ]),
        ],

6.处理js文件

第一步:npm install -D babel-loader @babel/core @babel/preset-env
       npm install @babel/plugin-proposal-class-properties -D  //可以解析类语法
       npm install @babel/plugin-transform-runtime -D  //可以解析部分es7语法,如es7
       npm install @babel/runtime --save-dev
第二步:在webpack.config.js中添加一条rules
    {
      test: /\.m?js$/,
      exclude: /(node_modules|bower_components)/,
      include: path.resolve(__dirname, 'src'), // 只编译src目录下的js文件
      use: {
        loader: 'babel-loader',
        options:{
            presets:[
                '@babel/preset-env'
            ],
            plugins:[
                '@babel/plugin-proposal-class-properties'
            ]
        }
      }
    }
注意:可以根据不同的环境配置不同的webpack
     在package.json中配置
        "scripts": {
            "build": "webpack --mode production --config webpack.config.prod.js",  // 生产环境
            "dev": "webpack-dev-server --mode development --config webpack.config.dev.js"  // 开发环境
          },

问:如何加上语法校验(即eslint)
    第一步:npm install eslint eslint-loader -D
    第二步:下载eslinttrc.json(下载地址:https://eslint.org/demo)
    第三步:修改文件名eslinttrc.json为.eslinttrc.json,放在根目录下
    第四步:配置webpack.config.js   
            {
                test:/\.js$/,
                use:{
                    loader:'eslint-loader',
                    options:{
                        enforce:'pre',          //保证在编译js之前执行
                    }
                }
            }

6.全局变量引用问题,以jQuery为例,如何将 暴 露 给 全 局 , 使 用 w i n d o w . 暴露给全局,使用window. 使window.

第一步:npm install jquery
第二步:在js文件中
        import $ from 'expose-loader?$!jquery';
        console.log(window.$);
第三步:npm install expose-loader
问:在js文件中写成这样很丑怎么办?可以简写成import $ from 'jquery';吗?
    可以在webpack.config.js中配置
        rules:[
            {
                test:require.resolve('jquery'),
                use:'expose-loader?$'
            }
        ]
    然后js中引用变为
        import $ from 'jquery';
        console.log(window.$);
问:可以直接简写成$吗?不用引入直接console.log($)
    第一步:注释上步配置
            {
                test:require.resolve('jquery'),
                use:'expose-loader?$'
            },
    第二步:        
            在webpack.config.js中配置
                const webpack = require('webpack');

            new webpack.ProvidePlugin({  // 在每个模块中都注入$
                $:'jquery'
            })
问:还有什么不用配置的方法可以使用console.log($)吗?    
    前提:注释掉上步配置
    第一步:在index.html中引入<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    第二步:在index.js中写入
            import $ from 'jquery';
            console.log($);
    第三步:在webpack.config.js中配置
            module.exports = {
                externals:{   // 这样在index.js文件中引入jQuery就不会被打包
                    jquery:'$'      
                },
            }       
    

问:loader有哪些分类?
    (1)内联loader,如expose-loader
    (2)pre loader,在普通loader前面执行
    (3)normal loader,普通loader
    (4)post loader,在普通loader后面执行

7.如何配置多页面应用?

其他设置都不变,修改的内容如下:
    module.exports = {
        entry: {   // 配置多页应用
            other: './src/other.js',
            index: './src/index.js',
        },      
        output: {                     // 文件出口
            path: path.resolve(__dirname,'dist'), // 文件出口目录路径
            filename:'[name].[hash].js',                  // 文件出口文件名
        },
        plugins:[
            new HtmlWebpackPlugin({
                template:'./src/index.html',
                filename:'index.html',
                minify:{         // 压缩html文件
                    removeAttributeQuotes: true,  // 删除双引号
                    collapseInlineTagWhitespace: true,  //压缩变成一行
                },
                hash: true,     // 引用js文件添加hash值
                chunks:['index']   // 代表只加载index.js
            }),
            new HtmlWebpackPlugin({
                template:'./src/other.html',
                filename:'other.html',
                minify:{         // 压缩html文件
                    removeAttributeQuotes: true,  // 删除双引号
                    collapseInlineTagWhitespace: true,  //压缩变成一行
                },
                hash: true,     // 引用js文件添加hash值
                chunks:['other']
            }),
        ],
    }

8.如果文件有代码报错,如何快速定位到报错的位置?

四种方式:
在webpack.config.js中配置:
1) devtool:'source-map':会单独生成一个sourcemap文件,会显示出来报错的行和列
2) devtool:'eval-source-map':不会单独生成一个sourcemap文件,但是可以显示行和列
3) devtool:'cheap-module-source-map':不会产生列,但是可以单独生成一个sourcemap文件
4) devtool:'cheap-module-eval-source-map':不会产生列,也不会生成sourcemap文件,它会集成在打包之后的文件中

9.实时打包

在webpack.config.js文件中配置
    module.exports = {
        watch:true,
        watchOptions:{
            poll: 1000, // 每秒询问1000次
            aggreateTimeout: 500, // 防抖 改动代码的500毫秒内不打包
            ignored: /node_modules/
        }
    }

10.如何每次打包生成最新的dist文件目录?即没有缓存

 第一步:npm install clean-webpack-plugin -D
 第二步:在webpack.config.js中配置
     const {CleanWebpackPlugin} = require('clean-webpack-plugin');
     plugins:[
         new CleanWebpackPlugin(), // 默认清除的是output文件夹
     ]

10.webpack解决请求跨域问题(例:webpack端口为8080请求node服务端口3000)

    devServer:{
        proxy:{
            '/api':{
                target:'http://localhost:3000', // 配置代理,以api开头的请求全部转换为http://localhost:3000
                pathRewrite:{'/api':''},
            }
        }
    },
问:如果只想单纯的模拟数据怎么办?
    devServer:{
        before(app){
            app.get('/api/user',(req,res)=>{
                res.json({name:'wq',age:20});
            })
        }
    }
问:可不可以不使用转发,在后端服务启动webpack端口?
    第一步:npm install webpack-dev-middleware -D
    第二步:在server.js中写入
            // 模拟服务端
            let express = require('express');
            let webpack = require('webpack');

            let app = express();

            // 中间件
            let middle = require('webpack-dev-middleware');

            let config = require('./webpack.config.js');

            let compiler = webpack(config);

            app.use(middle(compiler));

            app.get('/user',(req,res)=>{
                res.json({name:'wq',age:20});
            })

            app.listen(3000);
    第三步:执行node server.js,在浏览器中输入http://localhost:3000

11.resolve属性的配置(待更新。。。)

resolve:{
    extensions:['*', '.js', '.jsx'],   // 在引入文件的时候如果不写后缀,默认去找js结尾再去找css结尾的文件
    //  配置路径别名
    alias:{
        components: path.join(__dirname, 'src/components'),  // 在引入时无需写全路径
    },
},

12.定义环境变量

new webpack.DefinePlugin({
    DEV:JSON.stringify('dev')
})

13.区分不同的环境(配置开发环境和生产环境的webpack)

第一步:npm install webpack-merge -D
第二步:在根目录下新建webpack.dev.js和webpack.prod.js两个文件
        let {smart} = require('webpack-merge');
        let base = require('./webpack.base.js');
        module.exports = smart(base,{
            mode:'production',
            optimization:{       // 优化项
                minimizer:[
                    new UglifyjsWebpackPlugin(   // 压缩js
                        {
                            cache: true,
                            parallel: true,
                            sourceMap: true
                        }
                    ),
                    new OptimizeCssAssetsWebpackPlugin() // 压缩css
                ]
            },

        })
第三步:修改webpack.config.js文件名为webpack.base.js
第四步:修改package.json文件
            "scripts": {
                "build": "webpack --config webpack.config.js",
                "dev": "webpack-dev-server --config webpack.config.js"
            },

14.使用多线程打包

第一步:npm install happypack
第二步:配置webpack.config.js   
        rules:[
            {
                test:/\.js$/,
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src'), // 只编译src目录下的js文件
                use: 'HappyPack/loader?id=js'
            },
        ]

        plugins:[
            new HappyPack({
                id:'js',
                use:[
                    {
                        loader:'babel-loader',
                        options:{
                            presets:[
                                '@babel/preset-env',
                                '@babel/preset-react'
                            ],
                            plugins:[
                                '@babel/plugin-proposal-class-properties',
                                '@babel/plugin-transform-runtime'
                            ]
                        }
                    }
                ]
            })
        ]

15.在多入口文件中打包时提取抽离公共代码

optimization:{       // 优化项
    splitChunks:{    // 分割公共代码
        cacheGroups:{  // 缓存组
            common:{   // 公共的模块
                chunks:'initial',
                minSize:0,
                minChunks:2, // 公用超过两次
            },
            vender:{
                priority:1,  //增加权重
                test:/node_modules/,
                chunks:'initial',
                minSize:0,
                minChunks:2, // 公用超过两次
            }
        }
    }
},

16.webpack的懒加载与热更新

1)懒加载
    onClick = ()=>{
        console.log('点击');
        import('static/test.json').then(data =>{
            console.log('data',data.default);
        })
    }
2)热更新
    配置webpack.config.js

    devServer:{
        hot:true,     // 启用热更新
    }
    plugins:[
        new webpack.NamedModulesPlugin(),  // 打印更新的模块路径
        new webpack.HotModuleReplacementPlugin(),  // 热更新
    ]

17.PWA:渐进式网络开发应用程序(离线可访问)
前提:npm install workbox-webpack-plugin

第一步:配置webpack.config.js
	// PWA:离线加载应用
    new WorkboxWebpackPlugin.GenerateSW({
        // 1.帮助serviceworker快速启动  2.删除旧的servicework
        clientsClaim: true,
        skipWaiting:true
    })
第二步:在入口文件配置(一般是index.js)
	   // 注册servicework
		if ('serviceWorker' in navigator) {
		    window.addEventListener('load',()=>{
		    // /service-worker.js文件会自动生成,不用管它
		        navigator.serviceWorker.register('/service-worker.js')
		            .then(()=>{
		                console.log('sw注册成功')
		            })
		            .catch(()=>{
		                console.log('sw注册失败')
		            })
		    })
		}

18.externals:用于排除一些引入的模块,不进行打包,引用外部的模块。

externals: {
  vue: 'vue'
}

/--------------------------------------------------------------------------------------------------/
注:关于源码课程 https://www.bilibili.com/video/av51693431?p=28

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值