Таким образом, до сих пор мы создавали наши приложения Vue, используя стандартный тег сценария для Vue (в основном, мы можем медленно переходить из приложений jQuery/Knockout-heavy), но когда мы начинаем конвертировать наши более сложные приложения, я уже могут видеть проблемы обслуживания, которые мы собираемся продвигать вперед, если мы не сделаем переход к сборке CLI раньше, чем позже.
Теперь это не проблема для многих наших приложений, но, поскольку мы приняли подход "внутреннего CDN" на ранних этапах в наших приложениях Vue, объединение всего в Webpack похоже на шаг назад в универсальности. Сейчас мы обслуживаем 4 файла, а затем каждый маршрут в нашем MVC-приложении имеет свой собственный связанный с ним экземпляр Vue (т.е. About.js), который контролирует весь пользовательский интерфейс и его логику. Наш CDN обслуживает: 1. polyfills.js (для совместимости с браузерами), 2. vendor.js(axios, moment.js и несколько других), 3. vue.js(vue + vee-validate) и 4. components.js (наша собственная библиотека компонентов пользовательского интерфейса).
В общем, меня не волнует 1-3. Все они могут быть объединены в сборку CLI webpack. Это №4, на котором я повесил трубку, поскольку обслуживание через CDN позволило нам мгновенно выпустить обновления для всех наших приложений без запуска новой сборки. В настоящее время у нас есть только 7 приложений с полной версией Vue, но мы намерены в конечном итоге преобразовать все 80+ наших внутренних приложений, а также несколько существующих и новых внешних приложений в Vue. Если 30 из наших приложений используют один из наших общих компонентов, и его необходимо обновить для решения любых проблем с функциональностью, доступностью и т.д., Это означает, что мы должны перестроить все 30 приложений и направить их, что совсем не идеально.
Есть ли способ продолжить использование сборки CDN только для наших компонентов и рассказать остальное как SPA с Webpack?
Обратите внимание: это не то же самое, что ссылка на внешнюю JS-библиотеку, такую как jQuery. Я пытаюсь добавить компоненты Vue. Если вы загрузите библиотеку, подобную этой, и попробуйте импортировать компонент через:
<ComponentName/>
Vue даст вам консольную ошибку:
[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
Потому что нет импорта. Но попытка импортировать его также не будет работать, потому что она не существует в приложении, она внешняя.
Вы хотели бы управлять своими приложениями с помощью сборки CLI Vue Webpack, но сохраняя гибкость в использовании независимых компонентов Vue, то есть служили отдельными файлами, которые являются общими для нескольких приложений/проектов. Это архитектура, которую вы описываете с помощью "внутреннего CDN".
Как отметил @RandyCasburn, вы могли бы достичь вышеуказанной цели, просто разоблачив Vue
глобально (обычно загружая его в <script>
из CDN), а затем загружая свои независимые файлы, которые используют Vue.component
для регистрации ваших компонентов по всему миру.
Ссылка: Как импортировать компонент Vuejs в index.html?
Тем не менее, вы хотели бы иметь возможность разрабатывать эти независимые компоненты Vue как компоненты единого файла (SFC).
Я вижу в основном 2 интересных решения для описания, которое вы описываете:
<script>
и который регистрирует компонент глобально с помощью Vue.component
.Vue.component
, Vue.component
его открыть объект Vue Component configuration/options, чтобы он мог локально регистрироваться и загружаться асинхронно. Это требует больше работы, потому что вам нужно настроить каждую конфигурацию webpack для каждого приложения, чтобы асинхронно загружать несвязанные куски. Вариант 1: Преобразование Vue SFC в один JS файл с Vue.component
На самом деле есть недавний шаблонный проект, который предлагает эту функцию:
https://github.com/RonnieSan/vue-browser-sfc
Шаблон для установки сборки для компиляции компонентов одиночного файла (.vue) в автономный JS файл для использования в браузере
См. Также Компилировать компонент ".vue" в браузере, только с JS?
Он использует webpack для преобразования вашего файла .vue
в скомпилированный JS файл, который регистрирует компонент по всему миру с помощью Vue.component
.
Вы также можете сделать очень похожий процесс, используя Rollup вместо webpack, если вам нужен более компактный код. Используйте rollup-plugin-vue.
Преимущество такого подхода заключается в том, что его легко понять, вам просто нужно реорганизовать свой HTML для загрузки Vue, а затем всех ваших общих JS файлов компонентов. Даже во время разработки эти компоненты должны быть доступны по всему миру, поэтому среда выполнения Vue не должна жаловаться на "Неизвестный пользовательский элемент" и в вашем потребительском приложении просто не import
и не объявлять их.
Недостатком является то, что перед загрузкой необходимо загрузить все эти компоненты, независимо от того, используете вы их или нет.
Вариант 2: Преобразование Vue SFC в один JS файл в качестве объекта опций async
Это гораздо интереснее, но сложнее настроить правильно.
Как и предыдущее решение, со стороны компонента вы используете шаг сборки для преобразования файла SFC .vue
, но вам не нужна дополнительная оболочка с объявлением Vue.component
. Просто попробуйте webpack или Rollup обернуть объект параметров компонента в IIFE или UMD, который регистрирует объект в глобальном контексте.
Например, файл rollup.config.js
будет выглядеть так:
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, чтобы он не связывал файлы в приложении, а асинхронно загружал их из сети. Например:
components: {
'my-component': () => import('my-component'),
},
Для этого вы можете использовать dynamic-cdn-webpack-plugin, но вы должны предоставить свою собственную функцию resolver
, потому что по умолчанию module-to-cdn
использует собственный список модулей, который не настраивается.
Вы указываете свои компоненты в параметре dynamic-cdn-webpack-plugin only
array, предоставляете resolver
который имитирует module-to-cdn
но использует ваш собственный список. Например:
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',
},
},
},
};
Чтобы эта схема работала, вам также нужно указать свои компоненты как модули в ваших зависимостях package.json
, возможно, с фиктивным локальным путем в качестве спецификации версии, чтобы убедиться, что вы не пытаетесь загрузить их из реестра npm.
Преимущество в том, что вам не нужно касаться ваших файлов HTML, асинхронная загрузка напрямую управляется вашими приложениями. Вы можете связать Vue и не заботиться о порядке/последовательности загрузки. Компоненты CDN загружаются по требованию, когда это действительно необходимо.
Недостатком является то, что для всех ваших потребительских приложений требуется более сложная конфигурация webpack, но она полностью управляема.
Ну, технически вы можете использовать http-vue-loader, который будет загружать компоненты .vue
через HTTP. Однако есть некоторые ограничения, и это не рекомендуется для производства.
Вы пытались webpack.config.js
несколько точек входа в вашем webpack.config.js
? Затем вы можете использовать одну точку входа для загрузки только своих компонентов, а другую для всего остального. Я считаю, что примеры строк ниже с веб-сайта веб-сайта должны работать.
{
entry: {
app: './src/app.js', //Exports to /dist/app.js
search: './src/components.js' //Exports to /dist/components.js
},
output: {
filename: '[name].js', //[name] is replaced with the
//key names in the entry option(app & search)
path: __dirname + '/dist'
}
}
Затем вы создаете файл /src/app.js
который импортирует ваши элементы 1-3 и /src/components.js
который импортирует ваши .vue
файлы.