Library项目的Webpack配置
知乎上有个提问,叫“如何成为高级Webpack配置工程师”,戏谑Webpack已经复杂到成为一门专业学问了。但Webpack确实是非常复杂的,一般人只能做到入门而无法精通。Webpack的复杂性在于要完成各种各样的功能,即不仅要处理js、css、html、图片、字体等各种格式的前端资源,还要对这些资源进行转译、精简、提取、分割、打包等一系列操作。
Webpack在当前前端工程化中占有很重要的地位,前端工程化是为了提高前端开发的效率,但是前端工程化中的工具链配置的复杂度也逐渐提高。有时候新开一个项目,光是配置这些工具就要花一两天,这对于小型项目有点得不偿失。在配置工具链的时间花费大,诚然webpack本身配置参数多,我认为更重要的原因在于平时过于依赖于vue-cli、react-scripts这类自动化生成工具,没有具体地了解每个配置项的作用。
最近要开发一个可视化的JS库,但是vue-cli、react-scripts这类自动化生成工具主要针对的是SPA,对开发Library支持不好,因而尝试下手动配置webpack、eslint、babel、prettier这些工具。好在开发的是Library,主要处理JS代码,如果是SPA,那就需要处理各种各样的前端资源,还是建议使用vue-cli、react-scripts。
本文主要是做步骤记录,用于指导以后进行简单项目的手动配置,因而本篇文章不探讨深度内容。
生成package.json
这块没什么好说的,借助npm init
或yarn init
可以快速地生成package.json
文件。我通常习惯于先在scripts
中把主要的开发命令写出来,以下是我的scripts
配置:
1 | { |
上面的scripts
配置也体现了下文要讲的工程目录结构,即build
里面放webpack配置文件,src
里面放源代码,详细的内容在下一节描述。
main
默认是index.js
,即指向源代码的入口文件。但是本项目主要开发的库是作为其他项目的node_modules,一般不会再对库进行转译,所以为了方便将本库集成到前段工程项目中,main
应该指向转译好的UMD格式文件。本项目的main
配置为:
1 | { |
规划目录结构
我认为工程的目录结构非常重要,它能够反映代码的模块划分,好的目录结构让人赏心悦目、容易理解。我按照以下目录进行组织:
1 | build // 编译配置 |
配置webpack
Webpack 4刚发布,据说简化了配置,所以本项目就来尝尝鲜。Webpack 4相比原来需要额外安装一个webpack-cli,并且要求node版本不小于6.11.5,安装命令如下:
1 | npm install --save-dev webpack webpack-cli |
接下来就要配置webpack.dev.config.js
和webpack.prod.config.js
。webpack官方文档推荐用一个webpack.common.config.js
提取公共配置后,再用webpack-merge
合并。由于本项目配置比较简单,重复的地方不多,所以就不用引入额外的复杂度了。如果项目的配置复杂到同一种配置需要重复3次以上,那么还是需要采用webpack-merge
合并的,因为同时更改3个地方很容易出错。
本项目的webpack.dev.config.js
的配置如下:
1 | const path = require('path') |
本项目的webpack.prod.config.js
的配置如下:
1 | const path = require('path') |
以上有以下几个地方需要注意:
1.entry
中使用相对于当前目录时,./
不能省略,即./src/index.js
不能写为src/index.js
。
2.output
中的path
一定要是绝对路径;
3.libraryTarget
设为umd
以兼容浏览器和commonjs环境;
4.webpack 4新引入了mode
配置,会自动做一些优化,可以为development
或production
,不能省略mode
的配置;
5.mode
为development
时,HotModuleReplacementPlugin不是默认载入的,所以为了使开发时候能够热替换,需要手动加上这个配置;
配置babel
babel负责将高语言特性JS源代码转译为低语言特性JS代码,以兼容低版本浏览器,当前推荐采用babel-preset-env
,它能根据要兼容的浏览器版本,有选择性地转译,而不是像以前一样统统转译为ES5。
使用以下命令安装babel以及配套工具:
1 | npm install --save-dev babel-core babel-preset-env babel-loader |
.babelrc
配置如下:
1 | { |
配置eslint和prettier
eslint能够检查源代码中的格式错误以及少量的语法错误,prettier是用来自动地格式化代码。它们的主要区别在于,eslint主要用来检查代码格式,prettier主要用来修复代码格式。虽然eslint --fix
也能自动修复一些格式错误,但只能修复少数几种格式错误,功能十分有限。prettier的格式修复功能很强,但是如果代码中有错误,例如有尾逗号、引用未知变量,prettier不管这些,仍然帮你格式化,这就让你很难提早发现代码中的错误。
eslint和prettier相爱相杀,让它们和谐相处,才能更好地为我们提供服务。总体思想是eslint的检查规则尽量与prettier的格式规则保持一致,代码先用prettier格式化之后再用eslint --fix
修复并检查。
需要先安装一下几个包:
1 | npm install --save-dev eslint prettier eslint-config-prettier eslint-plugin-prettier prettier-eslint-cli |
eslint-config-prettier
是用来将prettier的格式化规则作为eslint的检查规则,eslint-plugin-prettier
则是用来对比prettier格式化前后,代码中出现的错误。prettier-eslint-cli
是用来依次执行prettier和eslint --fix
,自动格式化代码。
.eslintrc
的配置如下:
1 | { |
需要指出的是如果使用了ES6的import
和export
,则需要配置"sourceType": "module"
。
我是无分号党,.prettierrc
配置如下:
1 | { |
配置.gitignore
.gitignore
用来排除不需要git管理的文件,配置如下:
1 | .DS_Store |
总结
配置一个Library开发环境,分为生成package.json、规划目录结构、配置webpack、配置babel、配置eslint和prettier、配置.gitignore几个步骤。本文仅仅是流水账记录,深度不够,写到后面我都觉得乏味了,以后不写这种水文章了,匿了。
Author: jingsam
Link: https://jingsam.github.io/2018/03/06/webpack.html
License: 知识共享署名-非商业性使用 4.0 国际许可协议