【webpack配置工程师】系列一(核心概念篇)

2,976 阅读4分钟

前言

关于版本,我们讲述的是 webpack 4.0 版本

我希望大家在用 webpack 前,要搞清楚,我们为什么要用 webpack ,它存在的意义是什么?

webpack 基础概念

webpack 可以把它理解为一款工具,一款帮助我们打包的工具,也可以称之为前端构建工具。

简单来说 webpack 做的事情就是将一些特别复杂且浏览器无法识别东西,通过 webpack 编译、打包后,生成了浏览器可以识别的静态资源。

webpack 都能做哪些事情,举几个栗子:

  1. 文件打包(代码合并)
  2. 文件压缩(压缩体积)
  3. 代码转换(scss,less,es6)
  4. 代码分割(公共模块抽离)
  5. 模块合并(公共模块合并)
  6. 热更新(自动刷新)
  7. 代码校验
  8. 自动发布

我们需要做的就是在配置文件中写好配置,然后剩下的工作 webpack 会帮我们自动处理。

在使用 webpack 前,我们需要安装 Node.jsnpm,webpack 是基于node编写的,而npm则用来安装依赖。

webpack 文件结构

在安装开始前,我先说两个文件,以及它们的作用。

package.json

在安装 webpack 前,我们需要初始化一个 package.json 文件,它是项目的描述文件,它的内容是一个json对象。

例如:

  1. 项目名称(name)
  2. 项目版本号(version)
  3. 项目描述 (description)
  4. npm 命令(scripts)
  5. 项目依赖(dependencies)

package.json 可以手工编写,也可以用npm命令自动生成。

{
  //项目名称
  "name": "chom",                                
  //版本号
  "version": "1.0.4",                             
  //项目描述
  "description": "前端基础工具库",                
  //入口文件
  "main": "dist/chom.min.js",
  //依赖模块,生产模式
  "dependencies": {},
  //项目开发所需要的模块,以及版本,开发模式
  "devDependencies": {							 
    "@babel/cli": "^7.7.4",
    "@babel/core": "^7.7.4",
    "babel-loader": "^8.0.6",
    "eslint": "^6.7.1",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.10"
  },
  //npm 命令行缩写
  "scripts": {									
    "test": "echo \"Error: no test specified\" && exit 1",
    //比如 npm run build 
    "build": "webpack --config build/webpack.config.js",     
    "lint": "eslint src/**"
  },
  //作者
  "author": "Zhangwenqiang",
  //项目许可证
  "license": "ISC"                              
}

webpack.config.js

webpack 默认会读取 webpack.config.js 文件的配置信息,可以在webpack 源码中修改默认文件名,也可以按环境区分将webpack.config.js 拆分成多个文件,例如:webpack.base.js 、webpack.dev.js 、webpack.prod.js

webpack 结构组成

在了解 webpack 使用配置时,我们必须首先要熟悉 webpack 中几个的核心概念。

mode

在 webpack 中有两种常见的模式,一种是 development(开发模式),一种是 production(生产模式)

module.exports = {
    mode: 'development'
}

entry

entry 是 webpack 的入口文件

// 单个入口文件的简写语法

module.exports = {
    entry: './src/index.js' // entry 属性指定入口文件路径
};

output

output 是 webpack 打包之后输出的文件

// 单个入口文件的简写语法

module.exports = {
    entry: './src/index.js',
    output: { // output 属性指定打包之后的文件放在什么位置
        // filename 属性指定输出文件的文件名称
        filename: 'bundle.js',
        // path 属性指定输出目录的绝对路径
        path: '/dist'
    }
};

loader

loader 用于对模块的源代码进行转换

因为 webpack 只能理解 JavaScript,所以需要 loader 将其它类型的文件转化为 webpack 能够处理的有效模块

不同的 loader 完成不同的任务,下面的例子指定使用 css-loader 处理 CSS 文件

npm install --save-dev css-loader

module.exports = {
  module: {
    rules: [
      { test: /\.css$/, use: 'css-loader' }
    ]
  }
};

plugins

plugin 用于处理一些拓展任务,从打包优化和压缩,一直到重新定义环境中的变量

// 在打包过程中会使用UglifyJsPlugin这个插件来对代码进行一些压缩整理等
const webpack = require('webpack');
module.exports = {
  plugins: [
    new webpack.optimize.UglifyJsPlugin()
  ]
}

webpack 安装流程

具体的安装流程 webpack的安装和配置 .

大概流程是下载node.js,初始化项目,安装 webpack 与 webpack-cli

webpack 配置概念

这里我会介绍一些 webpack 常用插件的概念以及为什么要使用这些插件。

html-webpack-plugin

简单来说 html-webpack-plugin 的基本作用就是生成html文件。

前面提到过,webpack 默认只能处理 javascript 文件,显然我们的项目中不可能只存在js文件,我们需要 webpack 将html也进行打包处理,这个时候就需要用到 html-webpack-plugin

html-webpack-plugin 还有一个重要的作用是会将html文件中引入的外部资源,自动创建一个正确的路径。

例如a.html 引入了 a.js ,但通过 webpack 打包会把a.js与其他js文件进行打包,而a.html引入的路径已经失效,此时 html-webpack-plugin 会自动将a.html引入的文件路径修改成已经打包后的文件路径。

具体的使用方法 html-webpack-plugin的使用

样式处理

webpack 处理css文件一般需要用到 css-loaderstyle-loader

css-loader 的作用是解析css中的importurlrequire之类的语法,帮我们分析出各个css文件之间的关系,把各个css文件合并成一段css

style-loader 的作用是将css-loader 生成的css代码挂载到页面的header部分,见下图:

如果项目中用到了scss或者less,都需要安装想对应的loader,具体的使用方法 webpack 打包样式

转化es6语法

为什么要处理es6语法?

es6语法并不是所有浏览器都支持、都能运行,一些浏览器如果不支持那么就会报错,导致用户体验非常糟糕,这个时候我们就需要使用babel来将es6语法处理成es5语法,比如箭头函数map()等语法特性,转换成浏览器能够识别的,低级的JS语法,就可以解决这个问题。

关于es6的兼容性,大概是这个样子滴:

  1. Chrome 51 版起便可以支持 97%ES6 新特性。
  2. Firefox 53 版起便可以支持 97%ES6 新特性。
  3. Safari 10 版起便可以支持 99%ES6 新特性。
  4. IE Edge 15可以支持 96%ES6 新特性。Edge 14 可以支持 93%ES6 新特性。(IE7~11 基本不支持ES6win10之后的浏览器是edge。之前的是IE

具体的使用方法 webpack编译ES6

处理js语法校验

提到js语法校验,不得不提到 eslint

eslint 是什么?为什么我们要在项目中使用 eslint

eslint 是一个语法规则和代码风格的检查工具

它可以检测我们编写的代码,给代码一个规范,项目中的代码必须按照这个规范编写

统一代码规范对我们有哪些好处?

  1. 有些格式上的问题会导致我们在发布生产环境时出现一些莫名的错误
  2. 团队协作,团队保持同一个风格编写代码,代码的可读性以及可维护性都较为友好

具体使用的方法 webpack引入eslint详解

全局变量引入

做项目时我们可能会遇到这种场景:一个变量很多文件中都会用到,这变量可能是第三方包(比如 Jquery ),也可能是自己定义的一个工具类。

这种情况我们怎么办?难道要在所有页面中都引用这个变量吗?答案是否定的,这样会造成项目的维护成本很高。

那么我们该如何高效便捷的引入全局变量呢,其实有两种方式。

  1. 使用 webpack 模块 注册全局变量
  2. 将变量暴露给 window 对象 成为全局变量

这里要注意一下,webpack 是一个工具,在这个工具里面,有一个同名的模块,叫做 webpack,我们就用这个模块给每一个页面或者组件注入一个对象。

//以jquery为例
let Webpack = require('webpack')    // 引入webpack模块

module.exports = {
    plugins: [      // 这是一个插件,所以要在plugins属性中配置
        new Webpack.ProvidePlugin({
            $: 'jquery'
        })
    ],
}

这样我们直接就可以在页面或组件中直接使用jquery,例如:

console.log($)

第二种方法,我在这里就不阐述了,感兴趣的同学可以自行搜索,我个人还是比较喜欢用第一种方法的(主要是懒,有点写不动了)。

图片处理

webpack 在处理图片上通常会使用 file-loaderurl-loader

file-loader 的作用

file-loader 可以用来帮助 webpack 打包处理 png jpg jepg等格式的图片;

file-loader 打包图片会生成一个hash值作为图片的名字;

url-loader 的作用

url-loader 可以将图片转换成base64的图片格式,可以减少网站的http请求,但是若是相同图片被引用多次,每一次都转换成base64,会造成js性能损耗,因此是将图片资源转换为base64 还是采用 http 的方式,要看图片具体的使用方式了。

这里要注意一下,url-loader内部封装了file-loaderurl-loader不依赖于file-loader,即使用url-loader时,只需要安装url-loader即可,不需要安装file-loader

打包文件分类

在使用 webpack 打包时,可能要将css归类到css目录下,img归类到img目录下,我们也可能会在引用资源的时候加上域名前缀,这时候就用到了我们的打包文件分类。

给图片归类到img目录下

rules:[
		
	{
		test:/\.(png|jpg|gif)$/,
		use:{
			loader:'url-loader',
			options:{	limit:2,//200k,小于200k使用base64来转换
			outputPath:'/img/'//大于上面的limit的图片就会生成到dist下的img文件夹下,同时所有路径都会加上这个img/
			}
		}
	}
]

css归类到css目录下

plugins:[
	new MiniCssExtractPlugin({
		filename:'/css/[name].[chunkhash:8].css',//抽离出来的css的文件名称,并在dist下生成css文件夹,将该文件放到该css目录下,引入的时候会自动加上/css/
	})
]

对所有输出资源加域名前缀,在引用的资源前,统一加上这个额publicPath,比如打包后的css路径是 /css/main.css,那么引用的时候就会成为publicPath值+ /css/main.css

output:{
	filename:'bundle.[hash:8].js', 
	path:path.resolve(__dirname,'./dist'),
	publicPath:'http://www.yuhua.com',//在引用的资源前,统一加上这个额publicPath,比如打包后的css路径是css/main.css,那么引用的时候就会成为publicPath值+'css/main.css'
},

结语

文章断断续续大概用了两周左右完成的,全当是自己对 webpack 知识点的复习与总结了,在这里吐槽一句(写文章真的很累),后续会更新 webpack 核心配置篇、webpack 性能优化篇.

感谢看到这篇文章的你,烦请帮忙为我的文章点几个赞同,让更多需要的朋友看到,非常感谢。

已工作的,祝您工作顺利,事业有成!还在学习的,祝您一切顺利,学业有成!