#vue.js #vuejs2 #vue-cli #vue-composition-api #vue-cli-4
#vue.js #vuejs2 #vue-cli #vue-composition-api #vue-cli-4
Вопрос:
Любая помощь в решении следующей проблемы будет с благодарностью!
Ситуация:
Мой проект содержит два пакета:
-
дочерний компонент-библиотека
- содержит единственное представление
About.vue
, написанное в стиле composition-API (со вспомогательными библиотеками@vue/composition-api
vue2 иvuex-composition-helpers
) - экспортирует один
RouteConfig
- сборка как библиотека
views/About.vue
(дочерний элемент)<template> <div class="about"> <h1>This is an about page (as component lib)</h1> </div> </template> <script> import { defineComponent } from "@vue/composition-api"; import { createNamespacedHelpers } from "vuex-composition-helpers"; export default defineComponent({ components: {}, setup(_, { root }) { const { useGetters, useActions } = createNamespacedHelpers("account"); // error thrown here! } }); </script>
router/index.ts
(дочерний элемент)export const routes: Array<RouteConfig> = [{ path: "/", name: "About", component: () => import(/* webpackChunkName: "about" */ "../views/About.vue") }];
lib.ts
(дочерний элемент)export const routes = require("@/router").routes;
package.json
(дочерний элемент)"scripts": { "build": "vue-cli-service build --target lib --name child-component-lib src/lib.ts" ...
- содержит единственное представление
-
родительское приложение
- импортирует маршрут из
child-component-lib
своего маршрутизатора - содержит простое представление, в котором отображается одна строка текста и
<router-view />
package.json
(родительский)"dependencies": { "@tholst/child-component-lib": "file:../child-component-lib",
router/index.ts
(родительский)import { routes as childComponentRoutes } from "@tholst/child-component-lib"; const routes: Array<RouteConfig> = [...childComponentRoutes]; const router = new VueRouter({routes}); export default router;
App.vue
(родительский)<template> <div id="app"> <Home /> <router-view /> </div> </template> <script> import { defineComponent } from "@vue/composition-api"; import Home from "@/views/Home.vue"; export default defineComponent({ components: { Home }, setup(_, { root }) { ... } }); </script>
- импортирует маршрут из
Ожидаемое поведение
Она работает без проблем.
Фактическое поведение
Я вижу вывод ошибки в консоли. [Vue warn]: Error in data(): "Error: You must use this function within the "setup()" method, or insert the store as first argument."
Сообщение об ошибке вводит в заблуждение, потому что ошибка фактически выдается внутри setup()
метода. Это можно проследить до getCurrentInstance()
возврата undefined
(внутри @vue/composition-api
).
Расследование:
- Оказывается, ошибка исчезает, когда я включаю то же
About.vue
самое в само родительское приложение (просто переключите маршрут, чтобы попробовать), т. Е. Это работает, когда мы избегаем импорта из встроенной библиотеки. - Похоже, это проблема с настройкой сборки (одна из
vue.config.js
,webpack
,babel
,typescript
, …)
Воспроизвести ошибку:
1. Клонировать, устанавливать, запускать
git clone git@github.com:tholst/vue-composition-api-comp-lib.git amp;amp; cd vue-composition-api-comp-lib/child-component-lib amp;amp; npm install amp;amp; npm run build amp;amp; cd ../parent-app/ amp;amp; npm install amp;amp; npm run serve
или один за другим
git clone git@github.com:tholst/vue-composition-api-comp-lib.git
cd vue-composition-api-comp-lib/child-component-lib
npm install
npm run build
cd ../parent-app/
npm install
npm run serve
2. Откройте браузер
- Перейдите к http://localhost:8080/
3. Откройте инструменты разработки, чтобы увидеть ошибку
[Vue warn]: Error in data(): "Error: You must use this function within the "setup()" method, or insert the store as first argument."
found in
---> <Anonymous>
<App> at src/App.vue
<Root>
Скриншот ошибки
Информация об окружающей среде:
Node: 14.2.0
npm: 6.14.8
Chrome: 86.0.4240.198
npmPackages:
@vue/babel-sugar-composition-api-inject-h: 1.2.1
@vue/babel-sugar-composition-api-render-instance: 1.2.4
...
@vue/cli-overlay: 4.5.8
@vue/cli-plugin-babel: 4.5.8
@vue/cli-plugin-router: 4.5.8
@vue/cli-plugin-typescript: 4.5.8
@vue/cli-plugin-vuex:4.5.8
@vue/cli-service: 4.5.8
@vue/cli-shared-utils: 4.5.8
@vue/component-compiler-utils: 3.2.0
@vue/composition-api: 1.0.0-beta.19
@vue/preload-webpack-plugin: 1.1.2
typescript: 3.9.7
vue: 2.6.12
vue-loader: 15.9.5 (16.0.0-rc.1)
vue-router: 3.4.9
vue-template-compiler: 2.6.12
vue-template-es2015-compiler: 1.9.1
vuex: 3.5.1
vuex-composition-helpers: 1.0.21
npmGlobalPackages:
@vue/cli: 4.5.8
Ответ №1:
Я наконец понял, в чем были проблемы. Во-первых, возникла реальная проблема. Во-вторых, в локальной настройке разработки была проблема, из-за которой решения реальной проблемы выглядели так, как будто они не работают.
Фактическая проблема решение
Дочерняя библиотека компонентов объединяла свои собственные версии пакетов npm @vue/composition-api
и vuex-composition-helpers
. Это имело следующий эффект: когда я запускал родительское приложение, на самом деле было два экземпляра этих библиотек, и компонент vue из дочерней библиотеки-компонента обращался к неправильному объекту, который не был должным образом инициализирован.
Решение состояло в том, чтобы предотвратить объединение этих библиотек в дочернюю библиотеку компонентов, путем
-
создание их
devDependencies
иpeerDependencies
. -
указание webpack не связывать их
npm run build
.package.json
"dependencies": { ... }, "devDependencies": { "@vue/composition-api": "^1.0.0-beta.19", "vuex-composition-helpers": "^1.0.21", ... }, "peerDependencies": { "@vue/composition-api": "^1.0.0-beta.19", "vuex-composition-helpers": "^1.0.21" },
vue.config.js
configureWebpack: { externals: { "@vue/composition-api": "@vue/composition-api", "vuex-composition-helpers": "vuex-composition-helpers" }, ... }
Сложная проблема, которая усложняла ситуацию
Я пытался решить эту проблему локально, фактически не публикуя пакет. И, похоже, это сработало, потому что я видел ту же проблему локально, что и в опубликованных пакетах.
Я выполнил локальную разработку, напрямую связав библиотеки родительского приложения и дочернего компонента. Я пробовал оба
-
прямая зависимость от папки
package.json
"dependencies": { "@tholst/child-component-lib": "file:../child-component-lib", },
-
npm link
cd child-component-lib npm link cd ../parent-app npm link @tholst/child-component-lib
Оба подхода приводят к тому, что они фактически импортируют (= символическую ссылку на) папку дочерней библиотеки компонентов со всеми файлами и папками (вместо только файлов, которые будут опубликованы в пакете npm).
И это означало следующее: несмотря на то, что я исключил две библиотеки composition-API из пакета и сделал их зависимостями от разработчиков / одноранговых узлов (см. Решение Актуальной проблемы), они все еще были установлены и присутствовали в дочерних библиотеках component-lib node_modules
. И эта node_modules
папка была символически связана с пакетом родительского приложения. И таким образом дочерняя библиотека компонентов по-прежнему имела доступ к своей собственной копии библиотек, которые мы хотели исключить из сборки (см. Актуальную проблему).). И я все еще видел ошибку, как и раньше.
И таким образом, мой локальный подход к разработке скрыл тот факт, что решение реальной проблемы действительно работало.
Комментарии:
1. Я хотел бы видеть ваш пост раньше, столкнулся с точно такой же проблемой, и я так сильно старался найти решение!
2. @JoelPintoRibeiro Да, мне тоже потребовались дни борьбы!