vue cli build with target lib: "require is not defined" when component is imported

vue cli build with target lib: "require is not defined" when component is imported

我正在尝试将 Vue 组件导出为包,并使用 vue cli 构建 dist。我打算在 npm 上发布它,但我目前正在使用符号 link 进行测试。然而,即使是一个简单的 hello-world 项目,我也无法制作有效的包。

我创建了一个项目:

vue create hello-world

然后我修改了package.json:

  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --target lib --name vue-hello-world ./src/components/HelloWorld.vue",
    "lint": "vue-cli-service lint"
  },
  "main": "./dist/vue-hello-world.common.js",

那我打电话给

npm run build

并且编译没有错误。

然后我在另一个项目的vue组件中导入(我在node_modules中使用了符号link):

import HelloWorld from "hello-world";

在页面呈现时出现以下错误:

[Vue warn]: Failed to resolve async component: function MediaViewerPdf() {
  return Promise.all(/*! import() */[__webpack_require__.e(62), __webpack_require__.e(46)]).then(__webpack_require__.bind(null, /*! ./viewers/MediaViewerPdf.vue */ "./vuejs/components/mediaViewer/viewers/MediaViewerPdf.vue"));
}
Reason: ReferenceError: require is not defined

知道发生了什么吗?

备注:

target: "web"

编辑:我已经确认它不是来自符号 link,我直接在 node_modules.

上的包有完全相同的错误

完整代码的回购:https://github.com/louis-sanna/vue-hello-world

不确定您是如何创建符号 link,但您应该为此使用 npm link。如果您仍然遇到问题(就像我自己一样)我建议您尝试 npm-link-better:

npm install -g npm-link-better
cd vue-hello-world
npm link
cd ../hello-world
nlc -w vue-hello-world

关于构建组件库,我建议你看看vue-cli-plugin-component。这个插件已经很好地设置了 vue-cli 项目。

发生这种情况是因为 Vue CLI Webpack 默认设置不导入 commonjs 模块,如 package.json 中的 "main" 字段所述。所以问题在于尝试导入的项目,而不是导出组件的项目。

有两种方法可以尝试解决这个问题。

  1. 来自导入项目方

您可以通过为导入您的组件的项目安装 babel 插件并设置 babel.config.js

来解决这个问题
module.exports = {
  presets: [
    '@vue/app'
  ],
  plugins: [
    '@babel/plugin-transform-modules-commonjs', // leave to import .common.js files
    '@babel/plugin-transform-modules-umd'       // leave to import .umd.js files
  ]
}

但是单独这样做是不够的:您还需要导入 CSS ,通过将其添加到您的入口文件

中来导入库生成的
import 'hello-world/dist/vue-hello-world.css';

请注意,我只使用 yarn link 对此进行了测试,但我相信这将适用于导入的单独 npm 模块。

  1. 从图书馆那边

原始问题的意图(我想)- 我如何捆绑一个库,这样我的用户就不必在每次想使用它时都跳这个小舞步了?

选项 1:不捆绑它 - 提供 .vue 文件和源代码。只需将所有内容包含在模块的 'src' 目录中,写一个带有解释的自述文件并完成它。让导入项目搞定编译和打包。

选项 2:使用带有 Vue 插件的 rollup 将组件滚动到 bundle 中。有一个关于如何做到这一点的例子。在该示例中,您可以看到您的项目将能够导入 .esm build https://github.com/vuejs/rollup-plugin-vue/tree/master/cookbook/library

所以我在 vue-cli 回购上问了这个问题,我得到了解决方案! https://github.com/vuejs/vue-cli/issues/4245

结果 NODE_ENV 已经在我的 shell 中设置为 development,所以这是用于构建的模式。

只需要明确设置模式就可以了:

vue-cli-service build --target lib --name vue-hello-world ./src/components/HelloWorld.vue --mode production

您可能需要将其添加到 vue.config.js:

config
  .mode("production")