之前翻译过一篇 前端工程化发展历史 的文章,Webpack
、Babel
、Eslint
现在基本上就是前端项目的标配了。
但工作以后一般很少接触这些配置,都是在前人配置好的基础上去写业务代码。即使有机会从零配置一个项目,一般也不会自己手动建这些配置文件,直接用 create-react-app
、Ant Design Pro
等自动帮我们生成各个目录和配置文件就可以了,省时省力。
这篇文章的话就从零手动去配置一个前端项目,会涉及到 Webpack
、React
、Babel
、TypeScript
、Ant Design
、Sass
、Eslint
、Prettier
,本文的话就本着「不求甚解」的态度,主要过一下各个模块的使用,适合从零一步一步跟着操作。
前端工程化项目是建立在 node.js
环境下的,之后需要安装各个 npm
包,所以首先电脑必须已经配置好了 node
环境。
新建一个目录然后执行 npm init
来初始化一个项目。
1 | npm init |
然后一路回车就可以,只是生成了 package.json
文件,后续想改的话也能改。
Webpack
前端不断发展,但很多特性浏览器不一定会支持,ES6
模块,CommonJs
模块、Scss/less
、jsx
等等,通过 Webpack
我们可以将所有文件进行打包、压缩混淆,最终转换为浏览器识别的代码。
除了安装 Webpack
,我们需要安装对应的命令行工具 webpack-cli
,以及实现了热加载,也就是自动监听我们文件变化然后刷新网页的 webpack-dev-server
。
由于这些工具只在开发阶段使用,所以我们安装的时候可以加上 -D(--save-dev)
命令,这样开发环境就不会打包了。
1 | npm i -D webpack webpack-cli webpack-dev-server |
安装之后 package.json
会自动记录我们安装的 node
包,对应版本如下,如果安装的和我不一样的话,后边的一些配置可能略有不同。
1 | { |
接下来在根目录新建 webpack.config.js
进行项目的配置,主要配置入口文件,打包输目录,以及 devServer
的目录。
1 | const path = require('path') |
新建一下上边相应的文件。
main.js
文件主要实现在网页写 hello world
。
1 | // /src/main.js |
新建 dist
目录,在里边新建 index.html
文件,引入 <script src="bundle.js"></script>
。
1 |
|
最后在 package.json
新建两条命令,默认的 test
命令可以直接删掉了。
1 | ... |
执行 npm run dev
,此时会自动打开 http://localhost:8080/
。
React
React
可以让我们专注于构建用户界面,而不需要再手动维护 dom
元素的更新,当然还可以用 VUE
。
安装核心库 react
,以及渲染 Web
的 react-dom
。
1 | npm i react react-dom |
修改 src/main.js
体验一下。
1 | // /src/main.js |
npm run dev
看下效果:
这里会发现上边都调用了 React.createElement
来创建元素,如果页面复杂的的话,那一层套一层就太繁琐了,React
为我们提供了 JSX
语法来简化写法。
让我们改写一下:
1 | // /src/main.js |
但此时会发现项目跑不起来了
现在,我们就需要 Babel
了。
Babel
babel
可以为我们把各种语法、新功能转换为浏览器所能识别的 js
。这里我们先安装一下 babel
以及在 webpack
中使用的 babel-loader
。
1 | npm i -D @babel/core babel-loader |
然后在 webpack
中引入 babel-loader
,用来对 js
进行转换,更改 webpack.config.js
文件。
1 | const path = require('path') |
然后我们来安装 @babel/preset-react
来转换 jsx
语法。
1 | npm i -D @babel/preset-react |
在根目录新建 babel
的配置文件 babel.config.json
。
1 | // babel.config.json |
此时再运行 npm run dev
就发现项目成功跑起来了!
然后我们还可以安装一些其他 babel
以便使用最新的 ES
语法,比如箭头函数、async await
、问号表达式等等, 需要什么就可以配置什么。当浏览器不支持这些特性时,babel
可以帮我们实现 polyfill
进行降级。
@babel/preset-env
包含了许多 ES
的新特性,core-js
实现 ployfill
,通过这两个 babel
各种 ES
最新的特性就都可以放心使用了,如果有不满足的我们可以单独配置 babel
的插件。
1 | npm i -D @babel/preset-env core-js |
然后我们再修改下 babel
的配置文件。
1 | // babel.config.json |
其中 useBuiltIns": "usage"
代表自动判断每个文件是否引入 ployfill
,corejs: 3
是指定版本。
TypeScript
越来越多的项目引入了 TypeScript
,尤其是规模比较大的项目,通过 ts
可以让一些 bug
提前暴露,平时自己开发的话也可以引入 ts
,提前了解学习。
项目引入 ts
的话有两种方式:
- 使用
TypeScript Compiler (TSC)
将ts
编译为ES5
以便能够在浏览器中运行。并且使用TSC
进行类型检查。 - 使用
Babel
翻译TS
,使用TSC
进行类型检查。
这里的话使用第二种方式,让 Babel
和 TSC
各司其职。
首先安装 TypeScript
以及 React
的 type
。
1 | npm i -D typescript @types/react @types/react-dom |
根目录新建 tsconfig.json
进行 ts
的配置。
1 | // tsconfig.json |
"noEmit": true,
表明 ts
只做类型检查,不进行编译输出。
然后我们将 src/main.js
修改为 src/main.tsx
,并且加上类型。
1 | // /src/main.js |
接下来进行 babel
的配置,安装 @babel/preset-typescript
,将我们代码从 ts
转为 js
。
1 | npm i -D @babel/preset-typescript |
babel
配置文件中加入。
1 | // babel.config.json |
最后在 webpack.config.js
中 babel
匹配的路径中加入 tsx
。
1 | const path = require('path') |
我们可以全局安装一下 typescript
,便于使用 tsc
命令进行类型检查。
1 | npm install -g typescript |
可以运行一下 tsc -w
实时进行类型检查。
Ant Design
引入组件库,方便更快的开发。
1 | npm install antd |
顺便可以按照习惯把 main.tsx
中的 hello
组件抽离出来并且命名为 app.tsx
。
1 | // /src/App.tsx |
然后我们在 main.tsx
引入 antd
的 css
文件。
1 | // /src/main.tsx |
此时就需要在 webpack.config.js
配置文件中补上 css
的 loader
,先安装一下。
1 | npm i -D style-loader css-loader |
css-loader
可以让我们在 js
中引入 css
,style-loader
帮我们将 css
以 style
标签的形式插入到页面。
安装好后进行配置 loader
。
1 | const path = require('path') |
然后就成功引入日期选择器了。
Sass
Sass
是 css
的预编译器,可以让我们写样式更顺手,具体特性可以参考 官网,我用的最多的就是可以嵌套形式写 css
,很方便。
我们安装一下 Sass
以及它的 loader
。
1 | npm install sass-loader sass --save-dev |
然后在 webpack.config.js
配置一下
1 | const path = require('path'); |
在 App.jsx
加几个类名,引入 App.scss
。
1 | // /src/App.tsx |
新建 App.scss
,添加颜色实验一下。
1 | .app { |
npm run dev
看下效果
Eslint
可以配置 eslint
来进行语法上静态的检查,也可以对 ts
进行检查。
1 | npm i eslint -D |
可以全局安装一下 npm i -g npx
命令,能够更方便的运行 node_modules/.bin
目录下的命令.
不然的话我们要执行 eslint
命令的话需要执行 ./node_modules/.bin/eslint --version
才能取到。或者像上边为了执行 tsc
命令,全局安装了 typescript
。或者在 package.json
里边添加一个自定义命令。不过还是 npx
是最方便的。
让我们初始化 eslint
.
1 | npx eslint --init |
然后按照项目需要选择对应的选项,最后自动安装相应的依赖。
然后 eslint
就自动为我们生成了 .eslintrc.js
配置文件,顺便补一个 "node": true
,不然的话 module.exports
直接报错。
1 | module.exports = { |
然后我们在 package.json
中可以添加一个 lint
命令来修复代码。
1 | { |
然后执行 npm run lint
即可进行 eslint
的相关修复。
配合 Vscode
我们也可以做到边写代码边自动检测 eslint
,以及保存的时候自动修复 eslint
相关错误。
可以安装 Eslint
插件,以及在 vscode
的设置中加入以下配置,点击下图的右上角可以直接进行配置的编辑。
1 | { |
为了使用更完善的 eslint
配置,我们也可以直接引用腾讯 Alloy
团队的推荐配置,参考 这里。
Prettier
prettier
主要做代码风格上的检查,字符串双引号还是单引号?几个空格?类似这样的。
当然 eslint
也可以配置这些,但为了分离它们各自的职责,最好还是用 prettier
来格式化代码风格,先安装一下。
1 | npm i -D prettier |
然后新建一个配置文件 .prettierrc.js
,这里直接引用 腾讯 Alloy 团队推荐的配置。
1 | // .prettierrc.js |
同样的,为了保存的时候自动帮我们格式化,我们可以安装 Vscode
的 Prettier
插件,以及再修改 Vscode
的配置。
1 | { |
总结
通过上边一系列的操作后,就可以开始愉快的开始写项目了,经验有限,上边有问题的地方还请大家指出。
上边的代码都比较零碎,可以在 github 上看整个代码。
上边每一块都是一个很大的地方,未来的话会继续边学习边总结,欢迎一起交流。