需求列表

  • 开发服务,自动刷新。打包功能一次搞定
  • 多页应用
  • 使用ejs模板,要支持模块文件的引入
  • eslint,并在项目commit时自动执行eslint检查
  • ts支持
  • scss支持
  • 静态资源(静态图片和favicon.ico)
  • iconfont 支持
  • css需要和js分离,且静态资源有版本控制

安装依赖

  1. clean-webpack-plugin # 清除文件
  2. copy-webpack-plugin # 复制文件
  3. css-loader
  4. eslint
  5. @typescript-eslint/eslint-plugin
  6. @typescript-eslint/parser
  7. file-loader
  8. husky
  9. lint-staged
  10. mini-css-extract-plugin # js和css分离
  11. sass
  12. sass-loader
  13. terser-webpack-plugin
  14. ts-loader
  15. ts-node
  16. typescript
  17. #npm install clean-webpack-plugin copy-webpack-plugin css-loader eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser file-loader husky lint-staged mini-css-extract-plugin sass sass-loader terser-webpack-plugin ts-loader ts-node typescript --save-dev

webpack.config.js

const path = require('path');

const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const WebpackReadPages = require('./webpack.read.pages');

const webpackReadPages = new WebpackReadPages();

let webpackPlugins = webpackReadPages.htmlWebpackPlugins;
webpackPlugins = webpackPlugins.concat([
  new MiniCssExtractPlugin({
    filename: 'styles/[name].[fullhash:6].css'
  }),
  new FriendlyErrorsWebpackPlugin(),
  new CleanWebpackPlugin(),
  new CopyWebpackPlugin({
    patterns: [{
      from: path.resolve(__dirname, 'public'),
      to: path.resolve(__dirname, 'dist')
    }]
  })
])

module.exports = {
  mode: process.env.NODE_ENV || 'production',
  stats: 'normal',
  entry: webpackReadPages.entrys,
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'scripts/[name]-[fullhash:6].js'
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js', '.scss', '.css'],
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@assets': path.join(__dirname, 'src', 'assets')
    }
  },
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin({
      extractComments: false
    })],
    splitChunks: {
      chunks: 'all',
      name: 'vendor',
      minSize: 30000
    }
  },
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    port: 9000,
    inline: true,
    quiet: true,
    historyApiFallback: true
  },
  plugins: webpackPlugins,
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/i,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader'
        ]
      },
      {
        test: /\.(png|jpe?g|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              publicPath: '../images/',
              outputPath: 'images',
              name: '[name].[hash:6].[ext]',
              esModule: true
            }
          }
        ]
      },
      {
        test: /\.(woff|woff2|svg|eot|ttf)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              publicPath: '../images/',
              outputPath: 'font',
              name: '[name].[hash:6].[ext]',
              esModule: true
            }
          }
        ]
      },
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      { 
        test: /\.(ejs|html)$/i, 
          use: [
            { 
              loader: path.resolve(__dirname, 'webpack.ejs.loader.js'),
              options: {
                a: '111'
              }
            } 
          ] 
      }
    ]
  }
};

package.json

{
  "name": "webpack-demo",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "serve": "cross-env NODE_ENV=development webpack serve",
    "build": "cross-env NODE_ENV=production webpack",
    "lint": "eslint . --ext .ts",
    "test": "mocha -r ts-node/register test/**/*.test.ts"
  },
  "keywords": [],
  "author": "wenxue.cwx<coolman_84@163.com>",
  "license": "MIT",
  "devDependencies": {
    "@types/chai": "^4.2.14",
    "@types/jquery": "^3.5.4",
    "@types/mocha": "^8.0.4",
    "@typescript-eslint/eslint-plugin": "^4.9.0",
    "@typescript-eslint/parser": "^4.9.0",
    "chai": "^4.2.0",
    "clean-webpack-plugin": "^3.0.0",
    "copy-webpack-plugin": "^6.3.2",
    "cross-env": "^7.0.3",
    "css-loader": "^5.0.1",
    "ejs": "^3.1.5",
    "eslint": "^7.14.0",
    "file-loader": "^6.2.0",
    "friendly-errors-webpack-plugin": "^1.7.0",
    "html-webpack-plugin": "^5.0.0-alpha.14",
    "husky": "^4.3.0",
    "js-beautify": "^1.13.0",
    "lint-staged": "^10.5.2",
    "merge": "^2.1.0",
    "mini-css-extract-plugin": "^1.3.1",
    "mocha": "^8.2.1",
    "node-notifier": "^8.0.0",
    "sass": "^1.29.0",
    "sass-loader": "^10.1.0",
    "terser-webpack-plugin": "^5.0.3",
    "ts-loader": "^8.0.11",
    "ts-node": "^9.1.0",
    "typescript": "^4.1.2",
    "webpack": "^5.9.0",
    "webpack-cli": "^4.2.0",
    "webpack-dev-server": "^3.11.0"
  },
  "dependencies": {
    "clipboard": "^2.0.6",
    "jquery": "^3.5.1",
    "prismjs": "^1.22.0"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "src/**/*.{jsx,txs,ts,js}": [
      "eslint --fix"
    ]
  }
}

这里就是一堆配置,怼上就行了。

完整项目地址:https://github.com/myestorm/traditional-web.git