天天看點

umi 項目增加支援放置生成的靜态資源 (js、css、img、fonts) 的 (相對于 outputDir 的) 目錄,就比如 vue-cli 的 assetDirumi 項目增加支援放置生成的靜态資源 (js、css、img、fonts) 的 (相對于 outputDir 的) 目錄,就比如 vue-cli 的 assetDir

umi 項目增加支援放置生成的靜态資源 (js、css、img、fonts) 的 (相對于 outputDir 的) 目錄,就比如 vue-cli 的 assetDir

簡介:最近需要做一個背景系統,時間又比較充足,antd 和 Ant Design Pro 都已經更新到了 v4 ,于是就果斷嘗鮮了一波,遇到的問題也比較多,比較難解決的就是類似 vue-cli 的 assetDir 的問題,現把解決方案整理如下。

提示: 不要配置 config.optimization.splitChunks ,會導緻 umi 項目運作失敗。

1.項目主要依賴

package.json

{
  "dependencies": {
    "@ant-design/icons": "^4.0.0",
    "@ant-design/pro-layout": "^5.0.16",
    "@ant-design/pro-table": "2.3.4",
    "antd": "4.3.3",
    "axios": "^0.19.2",
    "braft-editor": "^2.3.9",
    "braft-polyfill": "^0.0.2",
    "classnames": "^2.2.6",
    "cropperjs": "^1.5.7",
    "font-awesome": "^4.7.0",
    "js-cookie": "^2.2.1",
    "js-md5": "^0.7.3",
    "lodash": "^4.17.11",
    "moment": "^2.25.3",
    "omit.js": "^1.0.2",
    "path-to-regexp": "2.4.0",
    "prop-types": "^15.7.2",
    "qs": "^6.9.0",
    "react": "^16.8.6",
    "react-cropper": "^1.3.0",
    "react-dom": "^16.8.6",
    "react-helmet-async": "^1.0.4",
    "umi": "^3.1.2",
    "umi-request": "^1.0.8",
    "use-merge-value": "^1.0.1"
  }
}
           

2.項目結構

├── config                 # 配置檔案,包含umi内置功能和插件的配置以及webpack和babel的配置。
    │   ├── config.dev.js      # 開發環境變量
    │   ├── config.js          # 配置檔案
    │   ├── config.prod.js     # 生産環境變量
    │   └── defaultSettings.js # 網站和antd的配置
    ├── public                 # 靜态檔案,不變化的logo和icon等
    ├── src                    # 主代碼檔案
        ├── assets             # 靜态檔案,網站需要的圖檔,字型等
        │
        ├── components         # jsx元件
        ├── global.jsx         # 全局js
        ├── global.less        # 全局樣式
        ├── icons              # 自定義svg圖示
        ├── layouts            # 網站基本布局,權限校驗
        ├── locales            # 語言配置
        ├── models             # store資料倉庫
        ├── pages              # 網站頁面
        ├── routes             # 網站路由檔案
        │
        ├── service-worker.js  # pwa檔案
        ├── services           # api接口
        │
        ├── styles             # 全局樣式
        │
        └── utils              # 工具,包含請求庫,本地存儲等

           

3.主要修改

chainWebpack

配置 (defaultSettings 和 routes 檔案可以根據自己項目删除)

config/config.js

// https://umijs.org/config/
import { defineConfig } from "umi";
import defaultSettings from "./defaultSettings";
import routes from "../src/routes";

const path = require("path");
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const isEnvProduction = process.env.NODE_ENV === "production";
const isEnvDevelopment = process.env.NODE_ENV === "development";
const resolve = (dir) => path.join(__dirname, dir);
const assetDir = "static";

const config = defineConfig({
  history: { type: "hash" },
  publicPath: "./",
  hash: true,
  antd: {},
  dva: {
    hmr: true,
  },
  chainWebpack(config, { env, webpack, createCSSRule }) {
    // 修改js,js chunk檔案輸出目錄
    config.output
      .filename(assetDir + '/js/[name].[hash:8].js')
      .chunkFilename(assetDir + '/js/[name].[contenthash:8].chunk.js')

    // 修改css輸出目錄
    config.plugin("extract-css").tap(() => [
      {
        filename: `${assetDir}/css/[name].[contenthash:8].css`,
        chunkFilename: `${assetDir}/css/[name].[contenthash:8].chunk.css`,
        ignoreOrder: true,
      },
    ]);

    // 修改圖檔輸出目錄
    config.module
      .rule("images")
      .test(/\.(png|jpe?g|gif|webp|ico)(\?.*)?$/)
      .use("url-loader")
      .loader(require.resolve("url-loader"))
      .tap((options) => {
        const newOptions = {
          ...options,
          name: assetDir + "/img/[name].[hash:8].[ext]",
          fallback: {
            ...options.fallback,
            options: {
              name: assetDir + "/img/[name].[hash:8].[ext]",
              esModule: false,
            },
          },
        };
        return newOptions;
      });

    // 修改svg輸出目錄
    config.module
      .rule("svg")
      .test(/\.(svg)(\?.*)?$/)
      .use("file-loader")
      .loader(require.resolve("file-loader"))
      .tap((options) => ({
        ...options,
        name: assetDir + "/img/[name].[hash:8].[ext]",
      }));

    // 修改fonts輸出目錄
    config.module
      .rule("fonts")
      .test(/\.(eot|woff|woff2|ttf)(\?.*)?$/)
      .use("file-loader")
      .loader(require.resolve("file-loader"))
      .tap((options) => ({
        ...options,
        name: assetDir + "/fonts/[name].[hash:8].[ext]",
        fallback: {
          ...options.fallback,
          options: {
            name: assetDir + "/fonts/[name].[hash:8].[ext]",
            esModule: false,
          },
        },
      }));

    // 添加gzip壓縮
    config.when(isEnvProduction, (config) => {
      config
        .plugin("compression-webpack-plugin")
        .use(CompressionWebpackPlugin, [
          {
            filename: "[path].gz[query]",
            algorithm: "gzip",
            test: new RegExp("\\.(js|css)$"),
            threshold: 10240,
            minRatio: 0.8,
          },
        ]);
    });
  },
  // 生産環境去除console日志列印
  terserOptions: {
    compress: {
      drop_console: isEnvProduction,
    },
  },
  locale: {
    // default zh-CN
    default: "zh-CN",
    // default true, when it is true, will use `navigator.language` overwrite default
    antd: true,
    baseNavigator: true,
  },
  dynamicImport: {
    loading: "@/components/PageLoading/index",
  },
  targets: {
    ie: 11,
  },
  // umi routes: https://umijs.org/docs/routing
  routes,
  // Theme for antd: https://ant.design/docs/react/customize-theme-cn
  theme: {
    // ...darkTheme,
    "primary-color": defaultSettings.primaryColor,
  },
  // @ts-ignore
  title: defaultSettings.title,
  ignoreMomentLocale: true,
  manifest: {
    basePath: "/",
  },
  devServer: {
    open: true,
    port: 8367,
  },
});

export default config;
           

4.打包後輸出的 dist 目錄

├── asset-manifest.json
├── favicon.ico
├── index.html
└── static
    ├── css
    ├── fonts
    ├── img
    └── js
           

參考連結

1.https://github.com/umijs/umi/blob/master/packages/bundler-webpack/src/getConfig/getConfig.ts

問題來源

1.https://github.com/umijs/umi/issues/4490

繼續閱讀