当前位置: 首页 > 知识库问答 >
问题:

前端 - 如何将vue项目进行拆分出来的打成独立的CDN包进行版本控制并引用?

耿志义
2024-07-21

vuecli4.5.13,vue3.4.31 elemet-plus~2.7.6
目前由于项目太大想对项目进行拆分,将部分功能打包以标签形式引入使用,可以减少代码体积和打包时间等,并且可以使用版本进行控制

想法是先将部分代码拆分成独立的组件项目打包成umd

打包命令

build:vue-cli-service build --target lib --inline-vue --dest lib src/components/index.js

src/components/index.js

import XLLogin from './HelloWorld.vue';
const components = {
    XLLogin,
};

function install(Vue) {
  const keys = Object.keys(components);
  keys.forEach((name) => {
    const component = components[name];
    Vue.component(component.name || name, component);
  });
}

export {
    XLLogin,
}

export default {
  install,
  ...components,
};

HelloWorld

<template>
    <div>
        <button>222</button>
        <el-button>我是 ElButton</el-button>
        <el-alert title="Success alert" type="success" />
    </div>
</template>

<script setup>
//  import { ElButton } from 'element-plus'q
// import { ElLoading, ElButton, ElAlert, ElMessage } from 'element-plus'
        console.log(window)
        const loading = ElLoading.service({
            lock: true,
            text: 'Loading',
            background: 'rgba(0, 0, 0, 0.7)',
        })
        ElMessage({
            message: 'Congrats, this is a success message.',
            type: 'success',
        })
        // XlLoading({
        //     message: 'Congrats, this is a success message.',
        //   type: 'error',
        // })
        setTimeout(() => {
            loading.close()
        }, 2000)
</script>

vue.config.js

const path = require( 'path' );
const AutoImport = require('unplugin-auto-import/webpack')
const ElementPlus = require( 'unplugin-element-plus/webpack' );
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
module.exports = {
    css: { extract: false },
  configureWebpack: {
        // externals: {
      // vue: 'Vue',
    //  'element-plus': 'element-plus',
    //  '@shining3d/ui-components':'@shining3d/ui-components',
    //  '@shining3d/xl-element-plus':'@shining3d/xl-element-plus',
    //  '@shining3d/matomo':'@shining3d/matomo'
    // },
        resolve: {
            symlinks: false,
            alias: { 
      }
        },
        plugins: [
            ElementPlus({
                resolvers: [ElementPlusResolver()],
                useSource: true
            }),
      AutoImport({
        resolvers: [ElementPlusResolver()],
      }),
      Components({
        resolvers: [ElementPlusResolver()],
      }),
        ]
    },
}

在项目的public/html中使用<script src="lib/xl-login@0.0.1.umd.js"></script>引入

遇到问题
1、如果按照上述打包方式增加--inline-vue的话报错

Uncaught TypeError: Cannot read properties of null (reading 'isCE')
    at renderSlot (runtime-core.esm-bundler.js:2093:1)
    at button2.mjs:72:23
    at normalizeChildren (runtime-core.esm-bundler.js:7382:1)
    at createBaseVNode (runtime-core.esm-bundler.js:7188:1)
    at _createVNode (runtime-core.esm-bundler.js:7265:1)
    at createBlock (runtime-core.esm-bundler.js:7117:1)
    at Proxy.<anonymous> (button2.mjs:43:38)
    at renderComponentRoot (runtime-core.esm-bundler.js:887:1)

2、如果不增加--inline-vue
那么必须在项目的html中增加
<script src="https://cdn.jsdelivr.net/npm/vue@3.4.31/dist/vue.global.prod.js"></script>
然后页面报错

runtime-core.esm-bundler.js:265 Uncaught 
TypeError: Cannot read properties of null (reading 'setupContext')
    at nM (vue.global.prod.js:5:25015)
    at e.useSlots (vue.global.prod.js:9:14301)
    at useButton (use-button.mjs:25:25)
    at setup (button2.mjs:21:84)
    at callWithErrorHandling (runtime-core.esm-bundler.js:195:1)
    at setupStatefulComponent (runtime-core.esm-bundler.js:7633:1)
    at setupComponent (runtime-core.esm-bundler.js:7594:1)
    at mountComponent (runtime-core.esm-bundler.js:5030:1)
    at processComponent (runtime-core.esm-bundler.js:4996:1)
    at patch (runtime-core.esm-bundler.js:4468:1)

如果只有一个div button是没问题的
但是引入element-plus之后,使用ElLoading,ElMessage没有问题,使用标签<el-></el->这种样式就存在问题了

参考了https://github.com/vuejs/core/issues/4344回答,使用vite解决,我准备尝试
希望能得到其他解决方案

到这我就不知道怎么做了,我的想法是将每个拆分出来的打成独立的包,最好是所有依赖全部在包内不依赖项目,vue可以script引入也行,但是走到这进行不下去了

共有1个答案

曾典
2024-07-21
  1. 问题太长,不太确定你的具体问题,说说我的做法
  2. 首先,只对非常边缘的项目做这样的操作,保证用户体验
  3. 边缘包构建成 ESM lib 包,方便的代码内 import(url)
  4. 主项目把这些仓库标记为 external,或者使用动态加载。前者要求 html 里要主动引用,并且绑定到 window;后者更自由一些,我比较喜欢
  5. 但是要注意,尽量不要在大规模生产环境中这么做,因为公共 cdn 可靠性并不高,性能也一般,尤其在大陆反问哪,通常不足以很好的支撑产品
 类似资料:
  • 问题内容: 我目前正在独自完成多个项目(至少开发部分仅由我自己完成:)。结合使用带有不同Java,R,SQL和其他源文件的Eclipse,我想知道哪种版本控制系统最适合我。 当时Eclipse IDE的历史似乎就足够了,但是我不确定在一个月/一年中是否会如此。 您会推荐什么解决方案,为什么? 更准确地说:如果我决定使用完整的版本控制系统,我一定会使用SVN或git。但是我不确定是否有必要… 问题答

  • 一个老项目 使用vue开发的,之前一直用node14运行的 领导希望高版本的也能运行,至少是node16. 但当我使用node16,npm install 去报错无法下载依赖,甚至无法运行

  • 针对 Subversion 1.4(根据r2866编译) 前言 序言 读者 怎样阅读本书 本书约定 排版习惯 图标 本书的结构 本书是免费的 致谢 来自 Ben Collins-Sussman 来自 Brian W. Fitzpatrick 来自 C. Michael Pilato Subversion是什么? Subversion的历史 Subversion的特性 Subversion的架构 S

  • 我正在处理Hadoop和Hive的输出文本文件,其中的文件有由Control-A分隔的字段。然后我使用Python逐行读取文件,但是字符串函数即使指定了分隔符也不能正确拆分。 然后,我编写了一个Python函数,该函数使用标准的Python习惯用法逐行读取文件: 但是,当我运行函数时,字符串没有正确拆分。每行中应该有四个令牌。 您可以在我的Python函数中看到,我尝试了三种不同的方法来拆分字符串

  • 我想用某个特定的版本(3.11.6)运行脚本,因为torch这个库暂时不支持python3.12。 但我用3.12版本作为主力,所以用virtualenv虚拟了一个环境。 问题是每次运行torch的程序都要进入这个虚拟环境,而我需要用传参的形式调用脚本,如: 给第三方程序调用的 之前想打包成exe,但pyinstaller问题太多,不会用,缺各种我没导入过的包(应该是使用的包依赖的),弄了一晚上还

  • Cadence工作流需要具有确定性,这意味着如果使用相同的输入参数执行工作流,工作流预计会产生完全相同的结果。 当我作为Cadence的新用户了解到上述需求时,我想知道当需要打破确定性的变化时,我如何才能长期维护工作流。 一个示例场景是,您有一个连续执行Activity1和Activity2的工作流,然后您需要更改这些活动的顺序,以便工作流在Activity1之前执行Activity2。还有许多其