Search code examples
typescriptvue.jsvuejs3vue-clielement-plus

How to exclude element-plus package (replaced by import CDN) when building with webpack (@vue/cli@next)?


I'm using @vue/cli 5.0.0-beta.3, vue 3.2.8 with element-plus 1.1.0-beta.8.

For the purpose of smaller size of build package, I try to exclude all third party dependencies (vue, vue-router, vuex, element-plus, etc) when building package with import CDN in index.html file:

<!DOCTYPE html>
<html lang="">
  <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">
    <!-- cdn import -->
    <!-- vue -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-router.global.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuex.global.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-class-component.global.min.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.css">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/index.js"></script>
    <!-- cdn import -->
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>Financial Tools</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

While I failed to exclude element-plus with vue.config.js file:

module.exports = {
  config.externals = {
    vue: "Vue",
    "vue-router": "VueRouter",
    vuex: "Vuex",
    "element-plus": "ElementPlus",
  }
}

vue/cli service start, the page console report error:

Uncaught ReferenceError: ElementPlus is not defined

Here's a sample project to reproduce this issue: https://github.com/linrongbin16/financial_tools_app3

And there's another error:

Uncaught ReferenceError: exports is not defined

Also comes from the element-plus CDN:

"use strict";Object.defineProperty(exports,"__esModule" ...

As a second thought, maybe there's something wrong with my tsconfig.json file:

{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "useDefineForClassFields": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

But since I'm new to vue3+typescript+element-plus, I have no idea why this happen and how to configure this.


Solution

  • If you check CDN links, all deps except element-plus load from dist folders. Those are compiled versions of the libs.

    Element-plus uses link https://cdn.jsdelivr.net/npm/[email protected]/lib/index.js. If you open the file, you can see things like require - this is clearly not a file for browser. It needs to be processed by Webpack 1st...

    The current docs recommend loading from cdn.jsdelivr.net/npm/element-plus when using jsDelivr but that URL load as lib file for some strange reason even they have set a default file for jsDelivr in package.json as "dist/index.full.js"

    So do not use a short path for now and use this link instead: https://cdn.jsdelivr.net/npm/[email protected]/dist/index.full.js