将CDN组件与CLI Build一起使用? [英] Use CDN Components with a CLI Build?

查看:87
本文介绍了将CDN组件与CLI Build一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,到目前为止,我们一直在构建我们的Vue应用程序,利用Vue的标准脚本标签(主要是因为我们可以慢慢从jQuery / Knockout重型应用程序转换),但是当我们开始转换我们更复杂的应用程序,如果我们不早点切换到CLI构建,我已经可以看到我们将继续推进的维护问题。

So, up until now, we've been building our Vue applications utilizing the standard script tag include for Vue (mostly so we can slowly transition from jQuery/Knockout-heavy apps), but as we start to convert our more complex apps, I can already see the maintenance issues we're going to have moving forward if we don't make the switch to the CLI build sooner than later.

现在,对于我们的许多应用程序而言,这不是问题,但由于我们在Vue应用程序的早期采用了内部CDN方法,因此在Webpack中捆绑所有内容似乎在多功能性方面有点退步。现在我们提供4个文件,然后我们的MVC应用程序中的每个路由都有自己的关联Vue实例(即:about.js),它控制整个UI及其逻辑。我们的CDN服务:1。polyfills.js(用于浏览器兼容性),2。vendor.js(axios,moment.js和其他一些),3。vue.js(vue + vee-validate)和4. components.js (我们自己的自定义UI组件库)。

Now, this isn't an issue for many of our apps, but since we adopted an "internal CDN" approach early on in our Vue apps, bundling everything in Webpack seems like somewhat of a step back in versatility. Right now we serve 4 files and then each route within our MVC app has its own associated Vue instance (ie: about.js) which controls the entire UI and its logic. Our CDN serves: 1. polyfills.js (for browser compatibility), 2. vendor.js (axios, moment.js and a few others), 3. vue.js (vue + vee-validate) and 4. components.js (our own custom UI component library).

一般情况下,我不关心1-3。这些都可以捆绑在webpack CLI构建中。我已经挂了4号,因为CDN上的服务让我们可以即时推送所有应用程序的更新,而无需运行新版本。目前,我们只有7个应用程序运行完整的Vue构建,但我们的目的是最终将所有80多个内部应用程序,以及几个现有和新的外部应用程序转换为Vue。如果我们的30个应用程序正在使用我们的共享组件之一,并且需要更新以解决任何功能,可访问性等问题,那意味着我们必须重建所有30个应用程序并推送它们,这根本不理想。

In general, I don't care about 1-3. These can all be bundled in the webpack CLI build. It's #4 that I'm hung up on, as serving over the CDN has allowed us to push updates to all of our apps instantaneously, without running a new build. Right now, we only have 7 apps running a full Vue build, but our intention is to eventually convert all 80+ of our internal applications, plus several existing and new external applications over to Vue. If 30 of our apps are using one of our shared components and it needs to be updated to address any functional, accessibility, etc. concerns, that means we have to rebuild all 30 apps and push them, which isn't ideal at all.

有没有办法继续为我们的组件使用CDN构建,并将其余部分捆绑为带Webpack的SPA?

Is there a way to continue to use the CDN build just for our components and bundle the rest as a SPA with Webpack?

请注意:这与引用外部JS库(如jQuery)不同。我正在尝试添加 Vue组件。如果从外部加载这样的库,然后尝试通过以下方式导入组件:

Please note: This is not the same as referencing an external JS library, like jQuery. I'm trying to add Vue Components. If you load a library like this externally and then try to import the component via:

<ComponentName/>

Vue会给你一个控制台错误说:

Vue will give you a console error saying:

[Vue warn]: Unknown custom element: <ComponentName> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

found in

    ---> <App> at src\App.vue
           <Root>

只需添加如下:

export default {
    name: 'app',
    components: {
       ComponentName
    }
}

将返回:

Uncaught ReferenceError: ComponentName is not defined

因为没有导入。但是尝试导入它也行不通,因为它在应用程序中不存在,它是外部的。

Because there's no import. But trying to import it also won't work, because it doesn't exist in the app, it's external.

推荐答案

你想要使用Vue webpack CLI构建来管理您的应用程序,但保持具有独立 Vue组件的灵活性,即作为多个应用程序/项目通用的单独文件。这是一个用内部CDN 描述的架构。

You would like to manage your apps with a Vue webpack CLI build, but keeping the flexibility of having independent Vue components, i.e. served as separate files that are common to several apps / projects. That is an architecture that you describe with an "internal CDN".

作为由@RandyCasburn指出,你可以通过简单地暴露 Vue来实现上述目标全局(通常从CDN加载< script> ),然后加载使用 Vue.component <的独立文件/ code>全局注册您的组件。

As pointed out by @RandyCasburn, you could achieve the above objective by simply exposing Vue globally (typically loading it in a <script> from a CDN) and then loading your independent files that use Vue.component to register your components globally.

参考:如何'将'Vuejs组件'导入index.html?

但是,你想要能够将这些独立的Vue组件开发为单个文件组件(SFC)。

However, you would like to be able to develop these independent Vue Components as Single File Components (SFC).

我基本上看到了两个有趣的解决方案,用于您描述的用法:

I see basically 2 interesting solutions for the usage you describe:


  1. 填补创建小型构建步骤工具的空白将您的SFC转换为普通的JS文件,可以通过< script> 标记加载,并使用 Vue.component <全局注册该组件/ code>。

  2. 不要构建通过 Vue.component 注册的JS文件,而是让它公开Vue组件配置/ 选项对象,以便它可以本地注册异步加载。这需要更多的工作,因为您需要设置每个消费者应用程序webpack配置以异步加载非捆绑的块。

  1. Filling the gap of creating the small build step tool to convert your SFC into a plain JS file, that can be loaded through a <script> tag and that registers the component globally with Vue.component.
  2. Instead of building a JS file that registers through Vue.component, make it expose the Vue Component configuration / options object, so that it can be locally registered and loaded asynchronously. This requires more work because you need to setup each consumer app webpack config to asynchronously load non-bundled chunks.

选项1 :使用 Vue.component将Vue SFC转换为单个JS文件

Option 1: Converting a Vue SFC to a single JS file with Vue.component

实际上有一个最近提供此功能的模板项目:

There is actually a recent template project that offers this feature:

https://github.com/RonnieSan/vue-browser-sfc


用于编译单个文件的构建设置模板组件(.vue)成独立的JS文件以便在浏览器中使用

Template for build setup to compile Single File Components (.vue) into a standalone JS file for use in the browser

另请参阅编译一个.vue浏览器中的组件,仅限JS?

它使用webpack将 .vue 文件转换为一个编译的JS文件,用 Vue.component 全局注册组件。

It uses webpack to convert your .vue file into a compiled JS file that registers the component globally with Vue.component.

你也可以做一个非常相似的过程使用Rollup而不是webpack,如果您感兴趣的是更精简的代码。使用 rollup-plugin-vue

You could also do a very similar process using Rollup instead of webpack, if leaner code is of interest to you. Use rollup-plugin-vue.

这种方法的优点是易于理解,你只需要重构HTML来加载Vue,然后是所有常见的组件JS文件。即使在开发过程中,这些组件也应该是全局可用的,因此Vue运行时不应该抱怨未知的自定义元素,并且在您的消费者应用程序中,只是不要 import /声明它们。

The advantage of this approach is that it is easy to understand, you just need to refactor your HTML to load Vue, then all your common components JS files. Even during development, these components should be globally available, so Vue runtime should not complain about "Unknown custom element", and in your consumer app, just do not import / declare them.

缺点是你必须先加载所有这些组件,无论你是否使用它们。

The drawback is that you have to load all these components before hand, whether you use them or not.

选项2:将Vue SFC转换为单个JS文件作为async选项对象

这一个更有趣,但设置更复杂。

This one is far more interesting, but more complicated to set up right.

与之前的解决方案一样,在组件方面,您使用构建步骤来转换SFC .vue 文件,但您不需要额外的包装器 Vue.component 声明。只需让webpack或Rollup将组件选项对象包装在IIFE或UMD中,即在全局上下文中注册对象。

Like the previous solution, on the component side, you use a build step to convert the SFC .vue file, but you do not need an extra wrapper with Vue.component declaration. Just have webpack or Rollup wrap the component options object in an IIFE or UMD that registers the object in the global context.

例如你的汇总。 config.js 文件看起来像:

For example your rollup.config.js file would look like:

import VuePlugin from 'rollup-plugin-vue'

export default {
  input: 'components/my-component.vue',
  output: {
    file: 'dist/my-component.js',
    name: 'MyComponent', // <= store the component on `window.MyComponent`
    format: 'umd',
  },
  plugins: [VuePlugin()]
}

然后在您的消费者应用上,您仍然 import()并声明您的组件,但您需要设置webpack配置,以便它不会将文件捆绑在应用程序中,而是从网络异步加载它们。例如:

Then on your consumer apps, you still import() and declare your components, but you need to setup the webpack configuration so it does not bundle the files in the app, but asynchronously loads them from the network. For example:

components: {
  'my-component': () => import('my-component'),
},

为此您可以使用< a href =https://github.com/mastilver/dynamic-cdn-webpack-plugin =nofollow noreferrer> dynamic-cdn-webpack-plugin ,但你必须提供自己的 resolver 功能,因为默认 module-to-cdn 使用自己的模块列表这是不可配置的。

For that you can use dynamic-cdn-webpack-plugin, but you have to provide your own resolver function, because the default module-to-cdn uses its own modules list that is not configurable.

您在dynamic-cdn-webpack-plugin的 数组选项,提供解析器 模仿 module-to-cdn 但使用您自己的列表。例如:

You list your components in dynamic-cdn-webpack-plugin's only array option, provide a resolver that mimics module-to-cdn but uses your own list. For example:

const modules = {
  'my-component': {
    var: 'MyComponent', // <= name under which the component will be stored.
    versions: {
      '*': {
        development: 'http://localhost:8080/my-cdn/my-component.js',
        production : 'http://localhost:8080/my-cdn/my-component.min.js',
      },
    },
  },
};

要使此方案有效,您还必须将组件列为<$ c $中的模块c> package.json 依赖项,可能带有虚拟本地路径作为版本规范,以确保您不会尝试从npm注册表加载它们。

For this scheme to work, you also have to list your components as modules in your package.json dependencies, possibly with a dummy local path as version spec, to make sure you do not try to load them from npm registry.

优点是您不必触摸您的HTML文件,异步加载由您的应用直接管理。您可以捆绑Vue而不关心加载顺序/顺序。 CDN组件在实际需要时按需加载。

The advantage is that you do not have to touch your HTML files, the async loading is directly managed by your apps. You can bundle Vue and do not care about the loading order / sequence. CDN components are loaded on demand when actually needed.

缺点是它需要为所有消费者应用程序提供更复杂的webpack配置,但它完全可以管理。

The drawback is that it requires a more complex webpack config for all your consumer apps, but it is totally manageable.

这篇关于将CDN组件与CLI Build一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆