二、webpack环境搭建 (上)(搭建react移动端组件库全套路)

592 阅读5分钟

webpack环境搭建

这一节我们要做的是搭建一个基于webpack能够运行react + typescript的开发环境

需要做的事情

对于一个新开始的项目,我们首先得捋一捋需要做那些事情

  1. 需要一个能够运行的开发环境(最基本的)
  2. 能支持react
  3. 能支持typescript
  4. 需要做移动端适配 主要是demo页面的展示
  5. 项目需要用到的样式,使用less
  6. 项目需要dev和prod两套环境(prod主要用来打包demo展示页面)
  7. 项目js使用eslint
  8. 项目ts代码使用tslint
  9. 项目需要配置lint-stage用来hook commit
  10. 项目需要使用commit提交规范
  11. 项目需要配置changeLog
  12. 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去开发我们的组件了。

接下来我们做一些项目的常规优化

常规配置

  1. 添加.gitignore 文件, 用来忽略在git提交时无需上传仓库的文件
  2. .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环境的区分。我们把这一部分放在接下来的一节去做。