用 webpack 创建项目后,我们需要对 Webpack 进行配置来支持更复杂的业务要求。
    1、Webpack 配置支持 ie,新增 .browserslistrc 文件

    1. // .browserslistrc
    2. [production]
    3. > 1%
    4. ie 9
    5. [modern]
    6. last 1 chrome version
    7. last 1 firefox version
    8. [ssr]
    9. node 12

    2、让 Webpack 支持 JSX、JS、TS、TSX,加入 ESLint 检查,支持 SASS。node 依赖单独打包,支持多页面,合并共用文件。

    1. const ESLintWebpackPlugin = require('eslint-webpack-plugin')
    2. const path = require('path')
    3. const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    4. const HtmlWebpackPlugin = require('html-webpack-plugin')
    5. const mode = 'production'
    6. module.exports = {
    7. mode,
    8. // 多页面
    9. entry: {
    10. main: './src/index.js',
    11. admin: './src/admin.js',
    12. obb: './src/obb.js'
    13. },
    14. resolve: {
    15. alias: {
    16. '@': path.resolve(__dirname, './src/')
    17. },
    18. extensions: ['.ts', '.js', '.jsx','.tsx'],
    19. },
    20. plugins: [
    21. new ESLintWebpackPlugin({
    22. // 增加什么后缀就检查什么文件
    23. extensions: ['.js', '.jsx', '.ts', '.tsx']
    24. }),
    25. // build 后分离出 css 文件
    26. mode === 'production' && new MiniCssExtractPlugin({
    27. filename: '[name].[contenthash].css'
    28. }),
    29. // build 后分离出 html 文件
    30. new HtmlWebpackPlugin({
    31. filename: 'index.html',
    32. chunks: ['index']
    33. }),
    34. new HtmlWebpackPlugin({
    35. filename: 'admin.html',
    36. chunks: ['admin']
    37. }),
    38. new HtmlWebpackPlugin({
    39. filename: 'obb.html',
    40. chunks: ['obb']
    41. })
    42. ].filter(Boolean),
    43. // build 后的 js 文件 hash 重命名
    44. output: {
    45. filename: '[name].[contenthash].js'
    46. },
    47. // 优化运行时配置
    48. optimization: {
    49. // 运行时runtime文件(webpack配置)单独打包, index.js 不变则不会生成新的 main.js,只更新 runtime.js,节省用户带宽。
    50. runtimeChunk: 'single',
    51. splitChunks: {
    52. cacheGroups: {
    53. vendor: {
    54. // 优先级
    55. priority: 10,
    56. minSize: 0, // 如果不写0,react 文件尺寸太小会被跳过
    57. test: /[\\/]node_modules[\\/]/, // 为了匹配 node_modules
    58. name: 'vendors', // 文件名
    59. chunks: "all" // all 表示同步加载和异步加载,async 表示异步加载,initial 表示同步加载
    60. // 这三行的意思是把两种加载方式的来自 node_modules 目录文件打包为 vendors.xxx.js, vendors 是第三方的意思
    61. },
    62. // 多页面共用文件配置
    63. commons: {
    64. priority: 5,
    65. minSize: 0,
    66. // 共用文件被至少两个文件引用了
    67. minChunks: 2,
    68. chunks: "all",
    69. name: 'commons'
    70. }
    71. }
    72. }
    73. },
    74. module: {
    75. rules: [
    76. {
    77. test: /\.[jt]sx?$/,
    78. exclude: /(node_modules|bower_components)/,
    79. use: {
    80. loader: 'babel-loader',
    81. options: {
    82. presets: [
    83. ['@babel/preset-env'],
    84. ['@babel/preset-react', {runtime: 'classic'}],
    85. ['@babel/preset-typescript']
    86. ]
    87. }
    88. }
    89. },
    90. // webpack 配置 sass
    91. {
    92. test: /\.s[ac]ss$/i,
    93. use: [
    94. // css支持导出, 给 JS 读取
    95. mode === 'production' ? MiniCssExtractPlugin.loader : 'style-loader',
    96. {
    97. loader: 'css-loader',
    98. options: {
    99. modules: {
    100. compileType: 'icss'
    101. }
    102. }
    103. },
    104. {
    105. loader: "sass-loader",
    106. // sass 自动导入全局,不用每个文件写import scss
    107. options: {
    108. additionalData: `
    109. @import "~@/scss-vars.scss";
    110. `,
    111. sassOptions: {
    112. includePaths: [__dirname]
    113. }
    114. }
    115. }
    116. ]
    117. }
    118. ]
    119. }
    120. }

    3、加入 ESLint 检查文件。

    1. // .eslintrc.js
    2. module.exports = {
    3. extends: ['react-app'],
    4. rules: {
    5. // 'react/jsx-users-react': [2],
    6. // 提示要在 jsx 里手动引入 React
    7. 'react/react-in-jsx-scope': [2]
    8. },
    9. // 引入 TS 检查
    10. overrides: [{
    11. files: ['*.ts', '*.tsx'],
    12. parserOptions: {
    13. project: './tsconfig.json'
    14. },
    15. extends: ['airbnb-typescript'],
    16. rules: {
    17. '@/typescript-eslint/object-curly-spacing': [0],
    18. 'import/prefer-default-export': [0]
    19. }
    20. }]
    21. }

    4、创建 tsconfig.json 文件并配置 TS

    1. tsc --init
    1. {
    2. "compilerOptions": {
    3. /* Visit https://aka.ms/tsconfig.json to read more about this file */
    4. /* Basic Options */
    5. // "incremental": true, /* Enable incremental compilation */
    6. "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    7. "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    8. // "lib": [], /* Specify library files to be included in the compilation. */
    9. // "allowJs": true, /* Allow javascript files to be compiled. */
    10. // "checkJs": true, /* Report errors in .js files. */
    11. "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    12. // "declaration": true, /* Generates corresponding '.d.ts' file. */
    13. // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
    14. // "sourceMap": true, /* Generates corresponding '.map' file. */
    15. // "outFile": "./", /* Concatenate and emit output to single file. */
    16. // "outDir": "./", /* Redirect output structure to the directory. */
    17. // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    18. // "composite": true, /* Enable project compilation */
    19. // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
    20. // "removeComments": true, /* Do not emit comments to output. */
    21. // "noEmit": true, /* Do not emit outputs. */
    22. // "importHelpers": true, /* Import emit helpers from 'tslib'. */
    23. // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    24. // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
    25. /* Strict Type-Checking Options */
    26. "strict": true, /* Enable all strict type-checking options. */
    27. "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
    28. // "strictNullChecks": true, /* Enable strict null checks. */
    29. // "strictFunctionTypes": true, /* Enable strict checking of function types. */
    30. // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
    31. // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
    32. // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
    33. // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
    34. /* Additional Checks */
    35. // "noUnusedLocals": true, /* Report errors on unused locals. */
    36. // "noUnusedParameters": true, /* Report errors on unused parameters. */
    37. // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
    38. // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
    39. // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
    40. /* Module Resolution Options */
    41. // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    42. // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
    43. // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    44. // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
    45. // "typeRoots": [], /* List of folders to include type definitions from. */
    46. // "types": [], /* Type declaration files to be included in compilation. */
    47. // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    48. "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    49. // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
    50. // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
    51. /* Source Map Options */
    52. // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    53. // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
    54. // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
    55. // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
    56. /* Experimental Options */
    57. // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
    58. // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
    59. /* Advanced Options */
    60. "skipLibCheck": true, /* Skip type checking of declaration files. */
    61. "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
    62. }
    63. }