webpack环境搭建
这一节我们要做的是搭建一个基于webpack能够运行react + typescript的开发环境
需要做的事情
对于一个新开始的项目,我们首先得捋一捋需要做那些事情
- 需要一个能够运行的开发环境(最基本的)
- 能支持react
- 能支持typescript
- 需要做移动端适配 主要是demo页面的展示
- 项目需要用到的样式,使用less
- 项目需要dev和prod两套环境(prod主要用来打包demo展示页面)
- 项目js使用eslint
- 项目ts代码使用tslint
- 项目需要配置lint-stage用来hook commit
- 项目需要使用commit提交规范
- 项目需要配置changeLog
- dll提升项目构建速度
开始撸代码
创建项目,xixi-mobile
mkdir xixi-mobile
cd xixi-mobile
yarn init
先搭建一个最简单的开发环境
首先安装需要的依赖项
yarn add webpack webpack-cli webpack-merge html-webpack-plugin less less-loader css-loader style-loader --dev
在项目下新建config文件夹用来放webpack的配置,先来一个最简单的webpack配置,让项目先能跑起来,然后我们在一步一步完成所有的功能
// merge用来合并webpack配置
const merge = require('webpack-merge')
// 将打打包文件自动注入html中
const HtmlWebpackPlugin = require('html-webpack-plugin')
// utils的resolve简单封装了一下path.resolve
const { resolve } = require('./utils')
const baseConfig = merge({}, {
mode: 'development',
entry: {
main: resolve('src/index.js')
},
output: {
filename: '[name].[hash:8].js',
path: resolve('dist')
},
module: {
rules: [
{
test: /\.less/,
include: [
resolve('src')
],
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'less-loader' }
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: resolve('src/index.html')
})
]
})
module.exports = baseConfig
这个webpack配置实现了组基本的功能,能打包less样式、能自动将打包文件注入html中。
在正式的项目,我们肯定不能每更改一次就进行一次编译打包,于是我们需要引入webpack-dev-server,用来在本地启动一个服务,在每一次修改后自动重新编译。接下来我们修改webpack配置
yarn add webpack-dev-server --dev
在最基础的配置上添加如下代码
devServer: {
public: '0.0.0.0',
port: process.env.PORT || 5678,
publicPath: '',
historyApiFallback: true,
overlay: true,
open: true,
contentBase: resolve('dist')
},
修改package.json上的scripts
"dev:demo": "webpack-dev-server --config ./config/webpack.base.js --color"
然后在终端中输入npm run dev:dmeo,0.0.0.0:5678会自动打开,然后就能看到我们的页面了
以上第一步我们就实现了配置一个最简单的webpack开发环境了。当然对于我们要做的事情来说,这只是最基础的一步,接下来我们接着配置react的开发环境
react开发环境配置
接下来我开始接入react,同样的我们只目前只是需要最简单的能将react跑起来就行,再react接入后我们再开始配置typescript。现在所有的webpack配置修改都是放在webpack.base.js里面。在基本搭建完成整个项目后,再对配置做优化。
为了编译react,我们还需要安装以下依赖
yarn add react react-dom react-router-dom
yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react --dev
我们先修改index.js中的内容,写一个最简单的react。
import './index.less'
import react from 'react'
import ReactDOM from 'react-dom'
ReactDOM.render(
<h1>xixi-mobile</h1>,
document.getElementById('root')
)
不出意料,此时终端报错了,因为我们还没有配置webpack,告诉它怎么识别jsx。 接下来修改webpack配置
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
然后新建.babelrc
{
"presets": [
'@babel/preset-env',
'@babel/preset-react'
]
}
以上配置完成后,我们重新启动项目,就能看到react已经成功的编译运行了。
现在react最基本的运行环境已经搭好,可是我们修改一下index.js,会发现现在随着代码的更新,页面是整体刷新的,而不是hot reload。接下来我们修改配置,完成hot reload
安装react-hot-loader
yarn add react-hot-loader
在devServer中配置hot: true,
plugins中引入webpack.HotModuleReplacementPlugin
devServer: {
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
然后在babelrc的配置中新加plugin用来react热更新
plugins: [
"react-hot-loader/babel"
]
最后在根组件上导出用hot包裹的高阶根组件就好了
app.js
import { hot } from 'react-hot-loader/root'
import React from 'react'
const App = () => {
return (
<div>xixi-mobile</div>
)
}
export default hot(App)
以上就完成了react的hot reload,这时我们再去更新app组件,会发现页面没有刷新,但是组件已经更新了。
配置typescript环境
完成了上面的配置后,我们已经搭建了一个大致的react开发环境了,接下来我们需要开始搭建typescript开发环境了
首先我们将index.js 和app.js 改为index.tsx和app.tsx
改完后我们会看到终端和页面上都报出了错误,You may need an appropriate loader to handle this file type
说明我们需要对tsx和ts后缀结尾的文件配置单独的loader
yarn add awesome-typescript-loader @types/react @types/react-dom @types/react-router-dom --dev
在webpack.base.js中对ts,tsx配置单独的loader,这个很简单了就不贴代码了, 配置项目tsconfig
{
"compilerOptions": {
"allowJs": true,
"allowUnreachableCode": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"baseUrl": "./src",
"moduleResolution": "node",
"module": "esnext",
"keyofStringsOnly": true,
"target": "esnext",
"jsx": "react",
"sourceMap": true,
"inlineSourceMap": false,
"inlineSources": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"noEmitHelpers": true,
"noEmitOnError": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"strict": true,
"strictNullChecks": true,
"noImplicitAny": true,
"noImplicitThis": true,
"suppressImplicitAnyIndexErrors": true,
},
"exclude": [
"node_modules"
],
"awesomeTypescriptLoaderOptions": {
"forkChecker": true,
"useWebpackText": true
},
"compileOnSave": false,
"buildOnSave": false
}
到这一步,我们已经能开始使用ts去开发我们的组件了。
接下来我们做一些项目的常规优化
常规配置
- 添加.gitignore 文件, 用来忽略在git提交时无需上传仓库的文件
- .editorconfig 编辑器配置
root = true
[*]
charset = utf-8
indent_size = 2
indent_style = space
insert_final_newline = true
end_of_line = lf
trim_trailing_whitespace = true
把我们之前的文件都格式化一遍
总结
以上我们已经搭建了一个可以开发react + ts的最基本的webpack配置了,当然这离我们搭建一个完善的组件库还有很多需要做的事情,剩下的事情我们放在下一节去做。
文末
还剩下一部分,主要是配置tslint, 项目优化,以及webpack配置的优化,dev和prod环境的区分。我们把这一部分放在接下来的一节去做。