webpack 多个代理_webpack核心概念

       webpack 作为目前最火热的模块打包器,是每一名前端工程师的必修课。我最近给自己放了两天假,梳理了 webpack 的核心概念及配置方式,在这里作出总结。

        对 webpack 讲解的最细致的地方肯定是 webpack 官网,但是官网内容比较繁杂,不方便随时查看。本文的目的是总结 webpack 基础核心知识点与用法,同时也给出了官网的相关部分说明的链接。想要了解更多细节,可以参看链接。

Loader

298fcfc7db9432e8fedf5f4bcc55861f.png

    webpack 自身只能识别、打包 js 文件,通过 loader 可以识别、处理各种类型文件,下面将介绍对图片、样式、字体、js(es6、react)文件的打包配置

一、图片文件打包

4e0c37acbd180fc0ca63e801bed69ffe.pngfile-loader 

作用是将指定类型文件移动到打包目录,并返回文件路径。用于处理各种不需要其他操作(比如转译)的文件。

module: {    rules: [      {        test: /\.(jpg|png|gif|svg)$/,        use: {          loader: "file-loader",          options: {            //placeholder:占位符              //name:源文件名称,ext:文件类型            name: "[name].[ext]",             //打包后文件存放路径            outputPath: "images/",          },        }      }    ] }

4e0c37acbd180fc0ca63e801bed69ffe.png url-loader

url-loader与 file-loader 都可以进行图片类型打包,但是 url-loader 可以将部分图片以 base64 的形式打包到js中( file-loader 只有移动文件的作用)。这就需要 limit 进行大小控制,图片大小小于 limit 指定的值(单位字节)图片将以 base64 形式打包到 js 中,大于限定值将还是按照图片形式打包。

  module: {    rules: [        use: {          loader: "url-loader",          options: {            name: "[name].[ext]",            outputPath: "images/",            limit: 2048, //2048字节 2K,小与2K以base64的形式打包到js中,大于两K,以图片形式打包。          },        }    ], }

二、样式文件打包

样式文件包括css、scss、less文件等,需要用到的 loader 如下:

4e0c37acbd180fc0ca63e801bed69ffe.png css-loader:分析css中几个css之间的关系,并将他们合并成一个

4e0c37acbd180fc0ca63e801bed69ffe.png style-loader:将合并好的css样式,以style标签的形式挂载到html 的header头中 

4e0c37acbd180fc0ca63e801bed69ffe.png sass-loader:解析sass文件

4e0c37acbd180fc0ca63e801bed69ffe.png postcss-loader:增加厂商前缀

补充一点:loader执行顺序是从下到上,从右到左的执行顺序~~

1. css文件配置:

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

2. 为 css3 标签增加浏览器厂商前缀:

{  test: /\.scss$/,  use: [    "style-loader",    "css-loader",    "sass-loader",    "postcss-loader",  ],},

配置postcss配置 文件:postcss.config.js

module.exports = {  plugins: [require("autoprefixer")],};

3. 为了避免不同模块间的样式冲突问题,可以开启css module

{  test: /\.scss$/,  use: [    "style-loader",    {      loader: "css-loader",      options: {        importLoaders: 2,        modules: true,      },    },    "sass-loader",    "postcss-loader",  ],},

三.字体文件打包

字体文件打包通过 file-loader (只需要进行文件移动即可)。  

{  test: /\.(eot|ttf|svg)$/,  use: {    loader: "file-loader",  },},

更多loader:

https://www.webpackjs.com/loaders/

Plugin

298fcfc7db9432e8fedf5f4bcc55861f.png

plugin 可以在 webpack 运行到某一时刻的时候帮你做一些事情,就像vue 与 react 中的生命周期函数

4e0c37acbd180fc0ca63e801bed69ffe.png html-webpack-plugin

使用该插件会自动生成 html 模版,并自动引入打包好的 js 文件(执行时期在打包之后)。也可以通过 template 配置生成 html 的模版

plugins: [  new HtmlWebpackPlugin({    template: "src/index.html",  }),],

4e0c37acbd180fc0ca63e801bed69ffe.png  clean-webpack-plugin

清除上次打包的内容,执行时期在打包之前

const { CleanWebpackPlugin } = require("clean-webpack-plugin"); plugins: [  new CleanWebpackPlugin()],

更多插件:

https://www.webpackjs.com/plugins/

entry与output

298fcfc7db9432e8fedf5f4bcc55861f.png

entry 与 output 是 webpack 中最基础的两个配置属性。entry 用于配置打包的入口文件,output 对打包文件的生成位置、名称等进行配置。

当对一个文件进行打包时,entry可以为: 

entry: {  main: "./src/index.js",},

  或者

entry: "./src/index.js",

可以通过output指定打包后的文件名:

output: {  filename: "bundle.js",  path: path.resolve(__dirname, "dist"),},

但是当需要打包成多个文件的时候,output 就不能指定死打包的文件名了(多个文件不可能重名嘛),就需要用到占位符 (下面的"name"就是占位符代表源文件名称,这样的占位符还有很多)

output: {  filename: "[name].js",  path: path.resolve(__dirname, "dist"),},

为了加快资源的加载速度,我们往往将静态资源放到 cdn 上,将 html 放到服务端。html 需要拉取 cdn 上的静态资源。这就需要修改 html 中引用的 js 的路径。可通过配置 output 的 publicPath 设定:

output: {  filename: "[name].js",  path: path.resolve(__dirname, "dist"),},

sourcemap

298fcfc7db9432e8fedf5f4bcc55861f.png

    当发生了异常为了能够快速定位到异常发生的位置,需要用到sourcemap。使用devtool控制sourcemap类型,sourcemap 的类型中有一些关键词,他们分别的含义如下:

  •   line:代表打包后的map文件会合并到打包的js文件中

  •   cheap:代表只能定位到行,定位不到那一列,但是性能更快

  •   eval:一种sourcemap的方式,打包速度最快,但是提示出来的内容可能并不全面,同时也不会生成 .map 文件

  •   module:添加module之后不仅负责业务代码的错误,同时第三方模块的错误也会展示。

  最佳实践:开发环境

{    mode: "development",    devtool: "cheap-module-eval-source-map",  }

最佳实践:生产环境 

{    mode: "production",    devtool: "cheap-module-source-map",  }

更多配置:

https://www.webpackjs.com/configuration/devtool/

    devserver    

298fcfc7db9432e8fedf5f4bcc55861f.png

         为了简化开发,当 src 下的代码变动之后希望能够对新的代码进行自动的打包编译,有几种方式:

  1. webpack --watch:在npm script中借助webpack的 --watch指令 能够监听文件变化重新打包,但是不可以打开浏览器,开启服务(还是以文件的形式打开页面)。

  2. 借助 webpack-dev-tool,通过 webpack-dev-tool 能够帮你开启一个服务,帮你实现:自动打开浏览器、代码更改后重新编译并刷新页面、提供服务端代理等等的功能,这是比较常用的一种方式 

配置如下:

  devServer: {    contentBase: './dist',//打包后的文件夹    open: true,//自动打开浏览器    port: 8080 //服务运行端口  },

更多配置:

https://www.webpackjs.com/configuration/dev-server/

HMR

298fcfc7db9432e8fedf5f4bcc55861f.png

当我们希望某一模块的变化不影响其他模块的方法,,不是每次变化都页面重新加载。这个功能叫做HMR(hot-module-replacement)。

官方说法是:

在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面 webpack官网

  HMR配置方式:

 const webpack = require("webpack");

  在plugin中新增:

plugins: [  new webpack.HotModuleReplacementPlugin(),],

  devServer 增加 hot 与 hotOnly 配置项:

devServer: {  contentBase: "./dist",//启动devserver的路径  open: true,//默认打开浏览器  port: 8080,//启动浏览器端口  hot: true,//是否启动热更新(HMR)  hotOnly: true,//即使不启动HMR(或者HMR有问题)也不刷新浏览器},

对于样式文件:当样式修改的时候,我们样式变化不会影响页面 js 渲染的渲染结果(css-loader已经帮我们完成了HMR的处理)。

对于js文件:当我们希望某一模块的 js 变动不影响其他的模块,我们需要使用代码控制,如下所示:(如果项目中使用了 babel-presets ,就不用再写这段逻辑了,babel-presets 已帮你完成配置):

if (module.hot) {  //支持hmr  module.hot.accept("xxx.js", () => {//某一个模块的js发生了变化执行逻辑    //...自定义执行逻辑  });}

babel

298fcfc7db9432e8fedf5f4bcc55861f.png

1. 安装 loader:

npm install --save-dev babel-loader @babel/core

2. 添加 webpack module配置:

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

3. @babel/preset-env 包含了所有转es5的语法规则,并将高级语法转换为es5语法,增加配置:

{  test: /\.js$/,  exclude: /node_modules/,  loader: "babel-loader",  options: {    presets: ["@babel/preset-env"],  },},

4. @babel/polyfill 为了兼容各大浏览器还需要引入 babel-pollify 对低版本浏览器进行补充(抹平了各个浏览器版本间的差异),比如帮助低版本浏览器实现 promise 、实现 map 方法等等

安装:

npm install --save @babel/polyfill

使用(在js中引用):

import "@babel/polyfill";

5. 如果不加配置,默认会将 @babel/polyfill 中所有的高级在低版本浏览器的实现都打进包里,这个包会变得非常大,我们只需要将用到的语法打进包里就可以了,通过 useBuiltIns 配置,配置方式如下:

module: {    rules: [      {        test: /\.js$/,        exclude: /node_modules/,        loader: "babel-loader",        options: {          presets: [            [              "@babel/preset-env",              {                useBuiltIns: "usage", //用到的才打包              },            ],          ],        },      }    ]  }

6. 更近一步,如果说可以限定支持的浏览器的版本号(比如项目只支持 IE10 以上),IE10 部分方法已经支持了,那么 pollify 包的大小就可以再进一步减小。示例配置如下:

module: {    rules: [      {        test: /\.js$/,        exclude: /node_modules/,        loader: "babel-loader",        options: {          presets: [            [              "@babel/preset-env",              {                targets: {                  edge: "17",                  firefox: "60",                  chrome: "67",                  safari: "11.1",                },                useBuiltIns: "usage", //用到的才打包              },            ],          ],        },      }    ]  }

7. @babel/polyfill 会污染全局环境,如果是写业务代码是没有问题的,但是如果是写类库,为了不污染引用者的全局环境使用 preset 的方式就不可取了,为了不污染全局环境可以使用引入 runtime 插件的方式:

  安装:

npm install --save-dev @babel/plugin-transform-runtimenpm install --save @babel/runtime  npm install --save @babel/runtime-corejs2

  webpack.config.js配置如下:

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,              version: "7.0.0-beta.0",            },          ],        ],      },    }  ]}

更多内容参看:

https://babeljs.io/docs/en/babel-plugin-transform-runtime

打包react代码

298fcfc7db9432e8fedf5f4bcc55861f.png

使用webpack打包react代码:@babel/predset 是将 es6 语法转换为 es5 语法,想要使用 webpack 打包 react 代码,除了要将 es6 语法转换为 es5 语法之外,还需要将 react 的 JSX 语法进行转换,这需要另外一个 preset:

  @babel/preset-react

安装:

  npm install --save-dev @babel/preset-react

可以使用 .babelrc 配置: 

{  "presets": [    [      "@babel/preset-env",      {        "targets": {          "edge": "17",          "firefox": "60",          "chrome": "67",          "safari": "11.1"        },        "useBuiltIns": "usage" //用到的才打包      }    ],    "@babel/preset-react" //从下往上,先转换react代码,再转换es6代码  ]}

更多参看:

https://babeljs.io/docs/en/babel-preset-react

拓展阅读

[1] webpack 官网:

https://webpack.js.org/

[2] webpack 中文官网:

https://www.webpackjs.com/

0041000e935dca16a8f104e5115fd280.png

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值