webpack学习笔记

安装
全局不推荐
npm install webpack webpack-cli -g//webpack-cli 可以帮助我们在命令行⾥使⽤npx ,webpack等相关指令
webpack -v
局部安装 项⽬内安装
npm install webpack webpack-cli --save-dev //-D
webpack -v //command not found 默认在全局环境中查找
npx webpack -v// npx帮助我们在项⽬目中的node_modules⾥查找webpack
安装指定版本
npm info webpack//查看webpack的历史发布信息 
npm install webpack@x.xx webpack-cli -D
webpack 配置文件
webpack有默认的配置文件,叫webpack.config.js,我们可以对这个文件进行修改,进行个性化配置,也可以不使用默认的配置文件。
默认的配置文件:webpack.config.js
npx webpack //执行命令后,webpack会找到默认的配置文件,并使用执行
不使用默认的配置文件: webpackconfig.js
 npx webpack --config webpackconfig.js //指定webpack使用webpackconfig.js文件来作为 配置文件并执行
Webpack 的核⼼心概念
entry
指定打包⼊⼝口文件
entry:{
  main: './src/index.js'
}
=====
entry:"./src/index.js"
output
打包后的文件位置
output: {
    publicPath:"xxx",
    filename: "bundle.js",
    // 必须是绝对路路径
    path: path.resolve(__dirname, "dist")
}
loader

webpack是模块打包工具,默认只知道如何处理js模块,⽽模块不仅仅是js,还可以是css,图片或者其他格式 ,那么其他格式的模块处理,和处理方式就需要loader了。
当webpack处理到不认识的模块时,需要在webpack中的module处进行配置,当检测到是什么格式的模块,使用什么loader来处理。


module: {
        rules: [
            {
                test: /.xxx$/,
                loader: 'xxx-loader',
                options: {
                   ...
                }
            }
        ]
},

常用loader

处理静态资源:

file-loader:处理静态资源模块。
原理是把打包⼊⼝口中识别出的资源模块,移动到输出⽬目录,并且返回一个地址名称。所以我们什什么时候用file-loader呢?场景:就是当我们需要模块,仅仅是从源代码挪移到打包⽬目录,就可以使用file-loader来处理,txt,svg,csv,excel,图片资源啦等等。
npm install file-loader -D
module: {
    rules: [
        {
            test: /.(png|jpe?g|gif)$/,
            loader: 'file-loader',
            options: {
                name: "[name]_[hash].[ext]",//[name]⽼资源模块的名称,[ext]老资源模块的后缀
                outputPath: 'img/'//打包后的存放位置
            }
        }
    ]
},
url-loader
可以处理file-loader所有的事情,但是遇到jpg格式的模块,会把该图片转换成base64格式字符串,并打包到js里。对⼩小体积的图片⽐比较合适,⼤大图片不合适。
module: {
    rules: [
        {
            test: /.(png|jpe?g|gif)$/,
            loader: "url-loader",
            options: {
                name: "[name]_[hash].[ext]", outputPath: "images/", //⼩小于2048,才转换成base64 limit: 2048
            }
        }
    ]
},
处理css
style-loader css-loader
css-loader 分析css模块之间的关系,并合成一个css;把css-loader⽣生成的内容,以style挂载到⻚页面的heade部分。
npm install style-loader css-loader -D
module: {
    rules: [
        {
            test: /.css$/,
            use: ["style-loader", "css-loader"]
        }
    ]
},
sass-load
sass-load 把sass语法转换成css ,依赖node-sass模块
npm install sass-loader node-sass -D
module: {
    rules: [
        {
            test: /.scss$/,
            use: ["style-loader", "css-loader", "sass-loader"]
        }
    ]
},
postcss-loader
样式⾃自动添加前缀
npm i -D postcss-loader
module: {
    rules: [
        {
            test: /.css$/,
            use: ["style-loader", "css-loader","postcss-loader"]
        }
    ]
},

安装autoprefixer

npm i autoprefixer -D
新建postcss.config.js
module.exports = {
   plugins: [require("autoprefixer")]
};
处理es6
babel-loader
babel-loader是webpack 与 babel的通信桥梁,不会做把es6转成es5的工作,这部分工作需要用到 @babel/preset-env来做;@babel/preset-env里包含了了es6转es5的转换规则。
npm i babel-loader @babel/core @babel/preset-env -D
通过上面的几步 还不够,Promise等一些还有转换过来,需要用@babel/plugin-transform-runtime,把es的新特 性都装进来,来弥补低版本浏览器器中缺失的特性
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
module.exports = {
    module: {
        rules: [
            {
                test: /.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    plugins: [
                        [
                            "@babel/plugin-transform-runtime",
                            {
                                "absoluteRuntime": false,
                                "corejs": 2,
                                "helpers": true,
                                "regenerator": true,
                                "useESModules": false
                            }
                        ]
                    ]
                }
            }
        ]
    }
}

如果觉着options的东西太多了,写这里不太合适,可以新建一个.babelrc文件。把options部分移⼊到该文件中。

//.babelrc 
{
   "plugins": [
        [
        "@babel/plugin-transform-runtime",
        {
            "absoluteRuntime": false,
            "corejs": 2,
            "helpers": true,
            "regenerator": true,
            "useESModules": false
            }
        ]
    ]
}
 //webpack.config.js
 {
     test: /.js$/,
     exclude: /node_modules/,
     loader: "babel-loader"
 }
配置React打包环境,安装babel与react转换的插件。 
npm install --save-dev @babel/preset-react
在babelrc文件里添加:
//.babelrc 
{
   "plugins": [
        [
        "@babel/plugin-transform-runtime",
        {
            "absoluteRuntime": false,
            "corejs": 2,
            "helpers": true,
            "regenerator": true,
            "useESModules": false
            }
        ],
        "@babel/preset-react"
    ]
}

plugins

plugin 是 wepback 的支柱功能。插件目的在于解决 loader无法实现的其他事,由于loader仅在每个文件的基础上执行转换,而插件(plugins) 常用于(但不限于)在打包模块的 “compilation” 和 “chunk” 生命周期执行操作和自定义功能。想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。

多数插件可以通过选项(option)自定义。

常用 plugins
HtmlWebpackPlugin
html-webpack-plugin会在打包结束后,自动⽣成一个html文件,并把打包生成的js模块引⼊到该html 中。
npm install --save-dev html-webpack-plugin
clean-webpack-plugin
清除打包生成的冗余重复文件
mini-css-extract-plugin
会在打包结束后,自动生成一个css文件,并把打包生成的css模块引⼊到html 中。
module.exports = {
    module: {
        rules: [
            {
                test: /.css$/,
                use: [
                    { loader: MiniCssExtractPlugin.loader },//用MiniCssExtractPlugin,这里就不是style-loade了
                    'css-loader', 'postcss-loader'
                ]
            }
            ...
        ]
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            title: '模板',
            template: './index.html'
        }),
        new MiniCssExtractPlugin({
            filename: '[name].css'
        }),

    ],
    ...
}
WebpackDevServer

提升开发效率的利器 每次改完代码都需要重新打包一次,打开浏览器,刷新一次,很麻烦 我们可以安装使用webpackdevserver来改善这块的体验。

npm install webpack-dev-server -D
module.exports = {
    ...
    devServer: {
        contentBase: "./dist",
        open: true,
        port: 8081
    },
}
启动服务后,会发现dist⽬目录没有了了,这是因为devServer把打包后的模块不会放在dist⽬目录下,⽽是放 到内存中,从⽽提升速度。

开发期间,webpack可以配置proxy搞定跨域,上线后我们使用nginx转发。

module.exports = {
    ...
    devServer: {
        ...
        proxy: {
            '/api': {
                target: 'http://localhost:9092'//所有以/api开头的请求都转发到http://localhost:9092
            }
        }
    },
}

 Hot Module Replacement (HMR:热模块替换)

启动hmr
const webpack = require("webpack");
...
module.exports = {
   ...
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ],
    devServer: {
        ...
        hot:true, 
        hotOnly:true,//即便便HMR不⽣生效,浏览器器也不⾃自动刷新,就开启hotOnly 
    },
}

这样至少css变化会引起热更新,但是js不会,要想使js热更新,还需要使用module.hot.accept来观察模块更新 从⽽更新。

//index.js
 if (module.hot) {
    module.hot.accept("./xxx", function() {
     ...
    }); 
}
sourceMap
源代码与打包后的代码的映射关系,
开发环境推荐:devtool:"cheap-module-eval-source-map"线上环境可以不开启:如果要看到一些错误信息,推荐devtool:"cheap-module-source-map"
devtool参数说明:eval:速度最快
         cheap:较快,不用管列的报错
         module:第三方模块
module.exports = {
    mode: 'development',
    devtool: "cheap-module-eval-source-map",
}
webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry: "./index.js",
    output: {
        // filename: 'pack.js',
        path: path.resolve(__dirname, './dist')
    },
    module: {
        rules: [
            {
                test: /.(png|jpe?g|gif)$/,
                loader: "url-loader",
                options: {
                    name: "[name]_[hash].[ext]", outputPath: "images/", //⼩小于2048,才转换成base64 limit: 2048
                }
            },

            {
                test: /.css$/,
                use: [
                    { loader: MiniCssExtractPlugin.loader },
                    'css-loader', 'postcss-loader'
                ]
            },
            {
                test: /.scss$/,
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            {
                test: /.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    plugins: [
                        [
                            "@babel/plugin-transform-runtime",
                            {
                                "absoluteRuntime": false,
                                "corejs": 2,
                                "helpers": true,
                                "regenerator": true,
                                "useESModules": false
                            }
                        ]
                    ]
                }
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            title: '模板',
            template: './index.html'
        }),
        new MiniCssExtractPlugin({
            filename: '[name].css'
        }),

    ],
    mode: 'development',
    devtool: "cheap-module-eval-source-map",
    devServer: {
        contentBase: "./dist",
        open: true,
        port: 8081,
        proxy: {
            '/api': {
                target: 'http://localhost:9092'
            }
        }
    },
}
原文地址:https://www.cnblogs.com/superlizhao/p/11384933.html