vue專案打包過大,使用cdn優化

江-月*夜發表於2020-11-25

一、在vue.config.js新增,如果沒有則新建

// 是否為生產環境
const isProduction = process.env.NODE_ENV !== "development";
// 本地環境是否需要使用cdn
const devNeedCdn = false;
const cdn = {
  // cdn:模組名稱和模組作用域命名(對應window裡面掛載的變數名稱)
  externals: {
    vue: "Vue",
    vuex: "Vuex",
    "vue-router": "VueRouter",
    axios: "axios",
    vant: "vant",
  },
  // cdn的css連結
  css: ["https://cdn.jsdelivr.net/npm/vant@2.10/lib/index.css"],
  // cdn的js連結
  js: [
    "https://cdn.jsdelivr.net/npm/vue@2.6/dist/vue.min.js",
    "https://cdn.jsdelivr.net/npm/vuex@3.5.1/dist/vuex.min.js",
    "https://cdn.jsdelivr.net/npm/vue-router@3.4.9/dist/vue-router.min.js",
    "https://cdn.jsdelivr.net/npm/vant@2.10/lib/vant.min.js",
    "https://cdn.jsdelivr.net/npm/axios@0.21.0/dist/axios.min.js",
  ],
}; 
module.exports = {
  lintOnSave: false,
  configureWebpack: (config) => {
    return {
      // 用cdn方式引入,則構建時要忽略相關資源
      externals: cdn.externals,
      //if (isProduction || devNeedCdn) {config.externals = cdn.externals}
    };
  },
  //打包忽略第三方庫
  publicPath: "./",
  chainWebpack: (config) => {
    // ============注入cdn start============
    config.plugin("html").tap((args) => {
      // 生產環境或本地需要cdn時,才注入cdn
      if (isProduction || devNeedCdn) args[0].cdn = cdn;
      return args;
    });
    // ============注入cdn start============
    //修改檔案引入自定義路徑
    config.resolve.alias
      .set("@", resolve("src"))
      .set("_api", resolve("src/api"));
  },
  
};

二、package.json修改
在package.json下修改(用到的cdn連結的,下面刪除,註釋會報錯)

"dependencies": {
    "compression-webpack-plugin": "^3.1.0",
    "core-js": "^3.6.4",
    "exif-js": "^2.3.0",
    "lib-flexible": "^0.3.2",
    "postcss-plugin-px2rem": "^0.8.1",
    "qs": "^6.9.1"
    // "axios": "^0.19.2",
	// "vant": "^2.5.2",
	// "vue": "^2.6.11",
	// "vue-router": "^3.1.5",
	// "vuex": "^3.1.2"
  },

四、inde.html檔案

<html lang="en" style="width: 100%;height: 100%;">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">

    <!-- 使用CDNCSS檔案 -->
    <% for (var i in htmlWebpackPlugin.options.cdn &&
    htmlWebpackPlugin.options.cdn.css) { %>
    <link
            href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"
            rel="stylesheet"
    />
    <% } %>
    <!-- 使用CDNCSS檔案 -->

    <title>CoolDream</title>
  </head>
  <body style="width: 100%;height: 100%;">
    <noscript>
      <strong>We're sorry but blog doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->

    <!-- 使用CDNJS檔案 -->
    <% for (var i in htmlWebpackPlugin.options.cdn &&
    htmlWebpackPlugin.options.cdn.js) { %>
    <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
    <% } %>
    <!-- 使用CDNJS檔案 -->

  </body>
</html>

五、壓縮檔案
1.安裝 
```javascript
npm i

compression-webpack-plugin -S

2.程式碼

```javascript
const CompressionPlugin = require("compression-webpack-plugin");
...
configureWebpack: (config) => {
    return {
      plugins: [
        new CompressionPlugin({
          test: /\.js$|\.html$|.\css/, //匹配檔名
          threshold: 10240, //對超過10k的資料壓縮
          deleteOriginalAssets: false, //不刪除原始檔
          minRatio: 0.8,
        }),
      ],
    };
  },

六、完整吃vue.config.js程式碼


```css
const path = require("path");
function resolve(dir) {
  return path.join(__dirname, dir);
}
const CompressionPlugin = require("compression-webpack-plugin");
// 是否為生產環境
const isProduction = process.env.NODE_ENV !== "development";

// 本地環境是否需要使用cdn
const devNeedCdn = false;
const cdn = {
  // cdn:模組名稱和模組作用域命名(對應window裡面掛載的變數名稱)
  externals: {
    vue: "Vue",
    vuex: "Vuex",
    "vue-router": "VueRouter",
    axios: "axios",
    vant: "vant",
  },
  // cdn的css連結
  css: ["https://cdn.jsdelivr.net/npm/vant@2.10/lib/index.css"],
  // cdn的js連結
  js: [
    "https://cdn.jsdelivr.net/npm/vue@2.6/dist/vue.min.js",
    "https://cdn.jsdelivr.net/npm/vuex@3.5.1/dist/vuex.min.js",
    "https://cdn.jsdelivr.net/npm/vue-router@3.4.9/dist/vue-router.min.js",
    "https://cdn.jsdelivr.net/npm/vant@2.10/lib/vant.min.js",
    "https://cdn.jsdelivr.net/npm/axios@0.21.0/dist/axios.min.js",
  ],
};
module.exports = {
  lintOnSave: false,
  configureWebpack: (config) => {
    return {
      plugins: [
        new CompressionPlugin({
          test: /\.js$|\.html$|.\css/, //匹配檔名
          threshold: 10240, //對超過10k的資料壓縮
          deleteOriginalAssets: false, //不刪除原始檔
          minRatio: 0.8,
        }),
      ],
      // 用cdn方式引入,則構建時要忽略相關資源
      externals: cdn.externals,
      //if (isProduction || devNeedCdn) {config.externals = cdn.externals}
    };
  },

  //打包忽略第三方庫
  publicPath: "./",
  chainWebpack: (config) => {
    // ============注入cdn start============
    config.plugin("html").tap((args) => {
      // 生產環境或本地需要cdn時,才注入cdn
      if (isProduction || devNeedCdn) args[0].cdn = cdn;
      return args;
    });
    // ============注入cdn start============
    //修改檔案引入自定義路徑
    config.resolve.alias
      .set("@", resolve("src"))
      .set("_api", resolve("src/api"));
  },
  transpileDependencies: [
    /[/\\]node_modules[/\\]test[/\\]/,
    /[/\\]node_modules[/\\][@\\]test2[/\\]test3[/\\]/,
  ],
  devServer: {
    port: 8085,
    disableHostCheck: true,
    proxy: {
      "/api": {
        target: "http://xxx", //API伺服器的地址
        changeOrigin: true,
        pathRewrite: {
          "^/api": "",
        },
      },
      "/fp": {
        target: "http://xxx", //API伺服器的地址
        changeOrigin: true,
        pathRewrite: {
          "^/fp": "",
        },
      },
    },
  },
};

相關文章