乐趣区

关于javascript:webpack-5-下的-reacttypescript

base-react-typescript

前言

本文次要写于 2021 – 02 – 09。应用时候须要看 package.json 的版本,防止出错。
全文次要讲述的是,从 0 开始搭建一个属于本人能够齐全管制的 react 我的项目。次要波及 webpack 逻辑,DLL 生成 等多个方面。后续会补充理论我的项目中应用等等。git 地址:https://gitee.com/sanyuelanv/…

我的项目框架

咱们先来简略的熟识一下整个我的项目的架构。在后续开发都依附着这一个架构去拓展。

├── app // 源码目录
│   ├── app.common.css // 全局的 CSS 代码,只须要一个!│   ├── app.html  // 模版 HTML
│   ├── app.tsx // 次要入口
│   ├── components // 组件
│   ├── config // 配置文件
│   ├── image // 图片素材
│   ├── router // 路由
│   ├── typings.d.ts // 全局 type
│   └── utils // 工具函数应用
├── build // 打包后目录
├── dll // 打包后目录
├── webpack.config.js // webpack 打包配置
└── webpack.dll.config.js // DLL 打包配置

依赖下载

  • devDependencies – 开发依赖包

    npm i --save-dev @babel/cli @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript  @types/react @types/react-dom  @typescript-eslint/eslint-plugin @typescript-eslint/parser autoprefixer babel-loader css-loader eslint eslint-plugin-react eslint-plugin-react-hooks file-loader html-webpack-plugin ip   postcss postcss-loader style-loader typescript url-loader webpack webpack-cli webpack-dev-server clean-webpack-plugin terser-webpack-plugin optimize-css-assets-webpack-plugin mini-css-extract-plugin add-asset-html-webpack-plugin html-webpack-tags-plugin copy-webpack-plugin

    依照完以上长长的开发依赖之后,咱们须要一个个去简略解析一下对应的作用

    • @types:@types 结尾的都是为 typescript 提供 type 内容的。比方你装置了 react 包,然而 vscode 在 node_modules/react 下 找到不到对的 *.d.ts 文件,就会倡议你装置一个 @types/react 依赖来便于辨认。其余第三方包同理。这里应用到的是 @types/react @types/react-dom 和 @types/react-dom 两个根底的依赖包。随着我的项目深刻,咱们会应用到更多的这类依赖包。
    • @babel:@babel 结尾的都是 babel 相干的工具包和插件。次要应用到有:@babel/cli @babel/core @babel/preset-env @babel/preset-react,其中性能作用,咱们能够在 webpack 配置的一章能够看到。
    • eslint 相干:eslint, @typescript-eslint/eslint-plugin, @typescript-eslint/parser, eslint-plugin-react-hooks 这些都是 eslint 的相干插件和次要逻辑包,具体作用在 eslint 配置能够看到。
    • webpack 以及它的助手们:残余的咱们都能够在 webpack 配置中看到他们的作用。它们一个个都为不同的文件 js / css / html / image 而来。
  • dependencies – 一般依赖包

    npm i --save core-js react react-dom  regenerator-runtime whatwg-fetch

    一般依赖包和下面的 devDependencies 不一样,它是须要打包进去咱们公布的 JS 文件中的。因而在后续减少和抉择的时候须要对他们的内容,大小进行剖析和理解才退出。防止打包进去的文件过大。

    • core-js:配合 webpack 能做到针对应用的 API 导入不同的补丁包去适配浏览器
    • regenerator-runtime:async 函数的补丁包,和 core-js 一样,配合 webpack 能做到主动导入。
    • whatwg-fetch: fetch 的补丁包,如果你更喜爱 axios 的话,能够不加这个。

webpack 配置

首先在 package.json 文件中的 scripts 加上对应的命令。这些命令的对应着 开发环境 / 正式环境 / DLL 的打包。这一节是讲述 开发环境 / 正式环境 的打包。次要都是在 webpack.config.js 这个文件中操作。

"scripts": {
  "dev": "webpack serve --env NODE_ENV=dev",
  "production": "webpack --env NODE_ENV=production --profile --json > stats.json",
  "dll": "webpack --config webpack.dll.config.js"
},

很多讲 webpack 的文章都喜爱把 webpack.config.js 离开成两个文件,再应用一些合并函数来合并通用的,而我这里更加偏差在一个文件中操作,依据 dev / production 命令中设置的 NODE_ENV 的不同去返回对应的 webpack 配置(webpack.config.js 的实质即便须要导出(module.exports)一个能 返回 webpack config json 的函数)。

webpack.config.js 中的内容很多,然而首先把它分成两局部。module.exports 之前的 和 module.exports 之后的。

  • module.exports 之后的

    • module – 模块

      在 webpack 眼中,我的项目内的所有文件都是 模块(module)。而在 webpack 的 module 字段中咱们须要做的就是制订规定(rules)。这个 rules 的次要作用是形容不同文件该由谁去解析(不同的 loader)。

      所以在整个 webpack.config.js 文件中你能看到很多的 xxLoaderxxxRule 对象。不同的 Loader 在 Rule 的 use 中进行组装。而 rule 则在本人的外部应用 test 和 include 字段去决定本人在哪一个目录下解决哪一类文件,所有的 rule 最终都在 config.module.rules 中拼接成一个数组。

      const fileRule = {test: /\.(png|svg|jpg|gif|woff|woff2)$/,
        use: [{
          loader: 'url-loader',
          options: isDev ? {limit: 2500} : {
            limit: 2500,
            outputPath: assestPathName,
            publicPath: `/${assestPathName}`
          },
        }],
        include: [appDir],
        exclude: [nodeModuleDir]
      }
      const baseConfig = {
        target: 'web',
        mode,
        entry: {'app': [path.resolve(appDir, 'app.tsx')] },
        resolve: {extensions: [".ts", ".tsx", '.js']
        },
        module: {
          rules: [
            typeScriptRule,
            javaScriptRule,
            modulesStyleRule,
            commonStyleRule,
            fileRule
          ]
        }
      }
    • plugins – 插件

      在 webpack 打包中,不同时间段是在做着这个不同的事件。而插件则能获取到这些不同的工夫点,不便你去做任何事件。没错,是任何事件。这就决定了 plugins 的性能是十分宽泛的。

      这里次要阐明几个插件的作用

      • DefinePlugin:定义全局变量,但在 typescript 中应用须要在 typings.d.ts 中把这个变量定义好,不然的话会提出正告。

        同时须要阐明一下这里不是给 __DEV__ 赋值,而是在编译的时候把 __DEV__ 替换成 true / false。配合上 webpack 的 Tree Shaking 咱们就能很不便设置一些配置文件:在开发环境的配置不会带在正式环境打包后的代码中

          // 须要在 typings.d.ts 中定义
          // declare const __DEV__: boolean
          new webpack.DefinePlugin({__DEV__: isDev}),
        
          // 应用
          const config = __DEV__ ? 'dev' : 'production'
          // DEV 编译后
          const config = true ? 'dev' : 'production'
          // Tree Shaking 后
          const config = 'dev' 
      • MiniCssExtractPlugin 把 CSS 抽离成独自的文件
  • module.exports 之前的
    在 module.exports 之前的大多是配置,以及和环境 (dev/dep) 无关的的 rule / loader 配置。

    // 开发代理服务器配置
    const ip = require('ip')
    ...
    // html Plugin 配置
    const baseHtmlWebpackPluginConfig = {
      filename: `index.html`,
      title: 'title',
      template: path.join(appDir, 'app.html'),
      inject: true
    }

DLL(Dynamic Link Library)

在 webpack.config.js 的文件中其实能够看到在 production 环境下,应用到 webpack.DllReferencePlugin。

const dllReferencePlugin = new webpack.DllReferencePlugin({context: process.cwd(),
  manifest: require('./dll/dll.manifest.json')
})

而这里应用到的 dll.manifest.json 文件则是咱们要见的 webpack.dll.config.js 配置下产生的。

webpack.dll.config.js 其实和 webpack.config.js 的正式环境差不多。只不过它只须要解决 ts 或者 js 文件(而且个别是依赖包下的 node_modules)。而它须要引入 webpack.DllPlugin 来导出一个清单文件(manifest.json)。这样在 webpack.config.js 中真正打包的时候就会跳过 manifest.json 上曾经打包的模块。间接应用 dll.js 提供的模块。

new webpack.DllPlugin({
  // 动态链接库的全局变量名称,须要和 output.library 中保持一致
  name: '[name]',
  // 形容动态链接库的 manifest.json 文件输入时的文件名称
  path: path.resolve(process.cwd(), 'dll', '[name].manifest.json')
})

DLL 的长处在于咱们无需频繁打包这些不常常更新的依赖包文件,在正式环境下打包的时候,DLL 相干文件其实是不再参加的。确保每次更新后用户须要再次下载的内容不会变动很大。

eslint 配置

详见 package.json 下的 eslintConfig 字段

browserslist 配置

详见 package.json 下的 browserslist 字段

退出移动版