图解Webpack之基础篇

开发 前端
本节主要用于入门webpack,首先用一张利用MindMaster绘制思维导图开篇来阐述本文的主要内容,读者可在此基础上进行扩展自己的思维导图。

[[421849]]

本节主要用于入门webpack,首先用一张利用MindMaster绘制思维导图开篇来阐述本文的主要内容,读者可在此基础上进行扩展自己的思维导图。

一、Entry

定义:指示webpack应该使用哪个模块,来作为构建其内部依赖图的开始。(从入口开始,搜寻并递归解析出所有入口依赖的模块)

1.1 单入口

对于单入口文件,其值为string类型,打包形成一个chunk,输出一个bundle文件。

  1. module.exports = { 
  2.     entry: './src/index.js' 

1.2 多入口

输入为一个数组,但是入口文件最终只会形成一个chunk,输出出去只有一个bundle文件。

  1. module.exports = { 
  2.     entry: ['./src/index.js','./src/add.js'

输入为对象,有几个入口文件就形成几个chunk,输出几个bundle1文件

  1. module.exports = { 
  2.     entry: { 
  3.         index'./src/index.js'
  4.         add'./src/add.js'
  5.     } 

1.3 动态入口

输入为一个函数(同步或异步),用于动态的返回上面所需的入口内容。

  1. module.exports = { 
  2.     entry: () => new Promise((resolve) => resolve(['./src/index.js','./src/add.js'])) 

二、Output

指示webpack如何去输出、以及在哪里输出你的bundle、asset 和其他你所打包或使用 webpack载入的任何内容。

2.1 名称

对于输出的名字,常用的主要有两类:filename(输出bundle名称)和chunkFilename(非入口chunk名称)。

filename(配置输出文件的名称,为string类型)

  1. module.exports = { 
  2.     //文件名称(指定名称+目录) 
  3.     filename: '[name].js' 

chunkFilename(配置非入口chunk的名称)

对于非入口文件,产生方式有两种:方式一是通过import语法会将一个文件单独分割成一个chunk;方式二是利用optimization将node_modules分割成chunk。(见后续博客)

  1. module.exports = { 
  2.     //非入口chunk名称 
  3.     chunkFilename: '[name]_chunk.js' 

2.2 路径

对于配置的输出路径,常用的主要有两个:path和publicPath。

path(配置输出文件存放的目录,必须是string类型的绝对路径)

  1. module.exports = { 
  2.  
  3. path: path.resolve(__dirname, 'dist_[hash]'
  4.  

publicPath(所有资源引入公共路径前缀)

  1. module.exports = { 
  2.     publicPath: 'https://cdn.example.com/' 

2.3 输出库

当用webpack去构建一个可以被其它模块导入使用的库时,需要用到libraryTarget和library。其中libraryTarget配置何种方式导出库;library配置导出库名称。

  1. module.exports = { 
  2.     library: '[name]'
  3.     libraryTarget: 'window',//var、assign、this、window、global、commonjs、commonjs2、amd、umd…… 

三、Loader

webpack只能理解JavaScript和JSON文件,通过loader让webpack能够去处理其它类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。

3.1 样式资源

对于css和less这样的样式资源,webpack不能直接进行处理,所以需要经过webpack翻译后才可以使用。此外不同浏览器对CSS的支持不同,为了CSS解决兼容性问题,可借助postcss-loader进行处理。

  1. module.export = { 
  2.     …… 
  3.     module: { 
  4.         rules: [ 
  5.             { 
  6.                 test: /\.css$/, 
  7.                 use: [ 
  8.                     //创建style标签,将js中的样式资源插入到html文件中。 
  9.                     'style-loader'
  10.                     // 将css文件变成commonjs模块加载到js中 
  11.                     'css-loader'
  12.                     'postcss-loader'
  13.                 ] 
  14.             }, 
  15.             { 
  16.                 test: /\.less$/, 
  17.                 use: [ 
  18.                     'style-loader'
  19.                     'css-loader'
  20.                     // 将less文件编译成css文件 
  21.                     'less-loader'
  22.                 ] 
  23.             } 
  24.         ] 
  25.     } 

3.2 图片资源

对于图片资源来说,主要可以分为html中图片和非html中图片。对于url-loader或file-loader能够处理js、css等中的图片资源,但是不能直接处理html中的图片资源,所以需要引用html-loader,负责引入img,从而能被url-loader进行处理。

  1. module.exports = { 
  2.     module: { 
  3.         rules: [ 
  4.             { 
  5.                 test: /\.(png|jpg|gif)$/, 
  6.                 loader: 'url-loader'
  7.                 options: { 
  8.                     limit: 8 * 1024, 
  9.                     name'[hash:10].[ext]'
  10.                     outputPath: 'asset/images' 
  11.                 } 
  12.             }, 
  13.             { 
  14.                 test: /\.html/, 
  15.                 loader: 'html-loader'
  16.             }, 
  17.         ] 
  18.     } 

3.3 js文件

因为每个人写代码的风格不同,为了统一js文件的风格,规范代码,可以采用eslint-loader进行处理。

  1. module.exports = { 
  2.     …… 
  3.     module: { 
  4.         rules: [ 
  5.             { 
  6.                 test: /\.js$/, 
  7.                 exclude: /node_modules/, 
  8.                 // 优先执行 
  9.                 enfore: 'pre'
  10.                 loader: 'eslint-loader'
  11.                 options: { 
  12.                     // fix: true 
  13.                 } 
  14.             } 
  15.         ] 
  16.     } 

此处可以用比较权威的Airbnb来进行语法检查,需要在package.json中添加:

  1. "eslintConfig": { 
  2.     "extends""airbnb-base"
  3.     "env": { 
  4.       "browser"true 
  5.     } 

不同浏览器对js代码的支持性不同,所以需要对js代码进行兼容性处理,可以利用babel-loader,配置方式主要有三种:

(1) 基本js兼容性处理-->@babel/preset-env

问题:只能转换基本语法,如Promise不能转换

(2)全部js兼容性处理--> @babel/polyfill

对于这个文件,只需要在js文件中直接引入即可 import '@babel/polyfill'; 这会将js有兼容性的东西全部带进来。

问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,导致文件体积太大了

(3)需要做兼容性处理的就做:按需加载 --> core-js

此时要把第二种方案的代码注释掉。

  1. module.exports = { 
  2.     …… 
  3.     module: { 
  4.         rules: [ 
  5.             { 
  6.                 test: /\.js$/, 
  7.                 exclude: /node_modules/, 
  8.                 loader: 'babel-loader'
  9.                 options: { 
  10.                     // 预设:指示babel做怎么样的兼容性处理 
  11.                     presets: [ 
  12.                         '@babel/preset-env'
  13.                         { 
  14.                             // 按需加载 
  15.                             useBuiltIns: 'usage'
  16.                             // 指定core-js版本 
  17.                             corejs: { 
  18.                                 version: 3 
  19.                             }, 
  20.                             // 指定兼容性做到哪个版本浏览器 
  21.                             targets: { 
  22.                                 chrome: '60'
  23.                                 firefox: '60'
  24.                                 edge: '17'
  25.                                 safari: '10'
  26.                             } 
  27.                         } 
  28.                     ] 
  29.                 } 
  30.             } 
  31.         ] 
  32.     } 

3.4 其它资源

对于不需要进行优化、压缩等进行处理的文件,例如字体图标、SVG等,可以直接被引入使用,这个时候用file-loader直接处理即可。

  1. module.exports = { 
  2.     module: { 
  3.         rules: [ 
  4.             { 
  5.                 exclude: /\.(css|js|html|less|jpg|png|gif)$/, 
  6.                 loader: 'file-loader'
  7.                 options: { 
  8.                     name'[hash:10].[ext]'
  9.                 } 
  10.             } 
  11.         ] 
  12.     } 

四、Plugin

插件目的是解决loader无法实现的其他事,可用于执行范围更广的任务,为webpack带来很大的灵活性。

4.1 HTML文件

为了简化HTML文件的创建,方便为webpack包提供服务,所以可以利用html-webpack-plugin插件。通过利用该插件可以自动引入JS、CSS等文件,可以对HTM代码进行压缩;此外,该插件还可以利用提供的HTML模板。

  1. module.exports = { 
  2.     plugins: [ 
  3.         // html-webpack-plugin插件,默认会创建一个空的HTML,自动引入打包输出的所有资源(JS、CSS) 
  4.         new HtmlWebpackPlugin({ 
  5.             // 需要有结构的HTML文件,可以通过配置template,复制该html文件,并自动引入自动引入打包输出的所有资源(JS、CSS) 
  6.             template: './src/index.html'
  7.             // 压缩html代码 
  8.             minify: { 
  9.                 // 移除空格 
  10.                 collapseWhitespace: true
  11.                 // 移除注释 
  12.                 removeComments: true
  13.             } 
  14.         }) 
  15.     ], 

4.2 CSS文件

对于CSS文件,利用插件主要需要处理三个方面:提取CSS文件、兼容性处理(配合postcss-loader)和对CSS文件进行压缩。

提取CSS文件:mini-css-extract-plugin

兼容性处理:post-preset-env

压缩:optimize-css-assets-webpack-plugin

  1. module.exports = { 
  2.     …… 
  3.     module: { 
  4.         rules: [ 
  5.             { 
  6.                 test: /\.css$/, 
  7.                 use: [ 
  8.                     // 'style-loader'
  9.                     MiniCssExtractPlugin.loader,// 用这个loader取代style-loader。作用:提取js中的css成单独文件 
  10.                     'css-loader'
  11.                     { 
  12.                         loader: 'postcss-loader'
  13.                         options: { 
  14.                             ident: 'postcss'
  15.                             plugins: () => [ 
  16.                                 require('postcss-preset-env')() 
  17.                             ] 
  18.                         } 
  19.                     } 
  20.                 ] 
  21.             }, 
  22.         ] 
  23.     }, 
  24.     plugins: [ 
  25.         new MiniCssExtractPlugin({ 
  26.             // 对输出的css文件进行重命名 
  27.             filename: 'css/[name].css' 
  28.         }), 
  29.         // 压缩css 
  30.         new OptimizeCssAssetsWebpackPlugin(), 
  31.     ] 

五、Mode

指示wenpack使用相应模式进行配置。

选项 描述
development 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。
production 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 TerserPlugin。
none 退出任何默认优化选项

 

本文转载自微信公众号「前端点线面」,作者前端点线面。转载本文请联系前端点线面公众号。

 

责任编辑:武晓燕 来源: 前端点线面
相关推荐

2021-09-06 06:45:06

Webpack优化MindMaster

2009-11-06 16:48:03

WCF简介

2010-05-27 17:41:09

2022-03-28 09:31:58

for循环语句

2011-01-18 10:00:59

Linux磁盘分区

2021-03-02 12:36:49

MQKafkaRocketMQ

2021-08-11 06:34:14

ZabbixDocker运维

2019-10-12 15:06:02

MySQL数据库命令

2024-02-02 10:38:06

虚拟文件系统VFS

2019-03-15 15:00:49

Webpack构建速度前端

2020-12-02 08:45:36

Go语言

2020-11-30 06:17:03

Go语言

2020-11-26 06:40:24

Go语言基础

2023-04-07 09:20:55

2009-06-30 11:18:16

HTML表单JSP教程

2012-02-29 01:03:10

ubuntuLinux

2020-11-23 08:54:14

Go语言结构体

2011-07-27 12:19:40

交换机集线器

2021-04-30 09:46:08

虚拟化Virtio-Net云计算

2022-03-10 09:33:21

Java数组初始化
点赞
收藏

51CTO技术栈公众号