webpack 配置(3)- 充实

536 阅读1分钟

之前的配置,在windows环境上运行没啥问题,但是在Mac上却是一堆bug,我也搞不清楚为啥,直到想到,会不会是不认识es6的语法?于是我立马配置了babel的基础

babel

yarn add babel-loader @babel/core @babel/preset-env
.babelrc

{
  "presets": [
    "@babel/preset-env"
  ]
}
webpack.config.js

module.exports = {
    ...
    resolve: {
      extensions: ['.js']
    },
    module:{
        rules:[
            {
              test: /.(js)$/,
              exclude: /node_modules/,
              use: ['babel-loader']
            },
        ]
    }
}

如此就算配置完成了,之后就发现我的css被正常解析了,于是得出结论,果然是babel的问题,而且注意到,babel的配置优先级应该高于css来配置。 细说Babel

细化babel

此时的babel是简单的版本的,功能是有了,但是如果要兼容比较低级的版本的时候,目前的babel是不够用的,此时遇到Promise等语法,babel会将这句话原封不动的返回,这跟我们的需求大相径庭。于是我们要升级babel的方法。目前babel的升级方案有两种,一个是ployfill垫片+corejs,但是这个会污染全局环境,还有一种是按需加载,@babel/plugin-transform-runtime,这种看你的情况,默认的corejs是false,也就是默认会看是否有全局的polyfill,所以默认的安装包名是

yarn add @babel/plugin-transform-runtime @babel/runtime

但是既然都用按需加载了,肯定是默认不会有polyfill了,于是我们用

yarn add @babel/plugin-transform-runtime @babel/runtime-corejs3
.babelrc

"plugins": [
  [
    "@babel/plugin-transform-runtime",
    {
      "corejs": 3
    }
  ]
]

js变成ts

现在谁还用js呢,所以既然babel都有了,这不用一波ts?注意,用了ts-loaderh之后,我们只能进行基本的转义,对Promise等语法还是没有办法很好的进行兼容,所以我们还是需要babel-loader。那么现有的ts的通行方案,总共也有三种,分别是

  • awesome-typescript-loader:这个好久没更新了,不考虑
  • ts-loader + babel-loader + fork-ts-checker-webpack-plugin
  • babel-loader + @babel/perset-typescript 现在网上的建议是老项目用第二种,新项目用第三种。我这里都是一下,以后的代码演示中还是2为主。
ts-loader + babel-loader + fork-ts-checker-webpack-plugin
yarn add  ts-loader fork-ts-checker-webpack-plugin typescript -D
webpack.config.js

const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin")

resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js']
},
module: {
    rules: [
        ...
        {
            test: /.(tsx?|jsx?)$/,
            exclude: /node_modules/,
            use: [
                'babel-loader',
                {
                    loader: 'ts-loader',
                    options: {
                        transpileOnly: true //只进行编译,不进行类型检查
                    }
                }]
        }
    ]
},
plugins:[
    new ForkTsCheckerWebpackPlugin()
]
babel-loader + @babel/perset-typescript
yarn add @babel/preset-typescript @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread typescript -D
webpack.config.js

resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js']
},
module: {
    rules: [
        ...
        {
            test: /.(tsx?|jsx?)$/,
            exclude: /node_modules/,
            use: ['babel-loader']
        }
    ]
},
.babelrc

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-typescript"
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-object-rest-spread",
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": 3
      }
    ]
  ]
}

但是这个没有办法类型检查,只能是tsc -w全局进行,体验不好

拆解webpack

在webpack中,有一个tree-shaking的功能,怎么开启呢,只需要在打包时候模式改成'production'即可,于是我们按照webpack文档,将文件分成webpack.config.dev.js(本地开发模式)和webpack.config.prod.js(用于上线的webpack的配置),以及原先的webpack.config.js三部分。然后将代码拆分

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin')

const path = require('path');

const cssLoader  = ()=>{
  return [
    process.env.NODE_ENV === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader,
    "css-loader",
    {
      loader: "postcss-loader",
      options: {
        postcssOptions: {
          plugins: [
            [
              'postcss-preset-env',
              {stage: 3}
            ]
          ]
        }
      }
    }
  ]
}

module.exports = {
  entry: './src/index.js', //webpack入口
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: "js/[name].[contenthash:8].js"
  },
  module: {
    rules: [
      {
        test: /.(js)$/,
        exclude: /node_modules/,
        use: ['babel-loader']
      },
      {
        test: /.css$/,
        use: cssLoader()
      },
      {
        test: /.s[ac]ss$/,
        use: [
          ...cssLoader(),
          'sass-loader'
        ]
      }
    ]
  },
  resolve: {
    extensions: ['*','.js']
  },
}
webpack.config.dev.js

const config =  require('./webpack.config.js')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const path = require('path')

//这个是用来开发的时候会进行的操作
module.exports = Object.assign({}, config, {
  mode: 'development',
  devServer: {
    port: '8080',
    hot: true, //开启热更新
    compress: true,  //开启压缩
    open: true //每次打开webpack的时候就能打开页面
  },
  plugins:[
    new HtmlWebpackPlugin({
      template: "./public/index.html"
    }),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, './public'),
          to: path.resolve(__dirname, './build'),
          noErrorOnMissing:true,
          globOptions: {
            ignore: [
              '**/index.html'
            ]
          }
        }
      ]
    }),
  ]
})
const  config =  require('./webpack.config.js')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin');
const {CleanWebpackPlugin} = require("clean-webpack-plugin");

const path = require('path')

//这个是用于生产环境的操作
module.exports = Object.assign({},config,{
  mode:'production',
  plugins: [
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: 'css/[name].[contenthash:8].css',
    }),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, './public'),
          to: path.resolve(__dirname, './build'),
          noErrorOnMissing:true,
          globOptions: {
            ignore: [
              '**/index.html'
            ]
          }
        }
      ]
    }),
  ],
})
package.json

{
  "name": "webpack-demo",
  "version": "1.0.0",
  "main": "index.js",
  "author": "xiaoznz",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.16.0",
    "@babel/plugin-transform-runtime": "^7.16.0",
    "@babel/preset-env": "^7.16.0",
    "@babel/runtime-corejs3": "^7.16.3",
    "babel-loader": "^8.2.3",
    "clean-webpack-plugin": "^4.0.0",
    "copy-webpack-plugin": "^9.0.1",
    "cross-env": "^7.0.3",
    "css-loader": "^6.5.1",
    "dart-sass": "^1.25.0",
    "html-webpack-plugin": "^5.5.0",
    "less": "^4.1.2",
    "less-loader": "^10.2.0",
    "mini-css-extract-plugin": "^2.4.3",
    "postcss-loader": "^6.2.0",
    "postcss-preset-env": "^6.7.0",
    "sass": "^1.43.4",
    "sass-loader": "^12.3.0",
    "style-loader": "^3.3.1",
    "webpack": "^5.61.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.4.0"
  },
  "scripts": {
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
    "start": "cross-env NODE_ENV=development webpack serve --config webpack.config.dev.js"
  },
  "browserslist": [
    ">0.2%",
    "last 4 versions",
    "Firefox ESR",
    "not ie < 9"
  ]
}