vue cli build with target lib:导入组件时“未定义要求”

Posted

技术标签:

【中文标题】vue cli build with target lib:导入组件时“未定义要求”【英文标题】:vue cli build with target lib: "require is not defined" when component is imported 【发布时间】:2019-11-16 11:06:44 【问题描述】:

我正在尝试将 Vue 组件导出为一个包,并使用 vue cli 构建 dist。我打算在 npm 上发布它,但我目前正在使用符号链接进行测试。然而,即使是一个简单的 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 中使用了符号链接):

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

知道发生了什么吗?

备注:

使用vue inspect,我在 webpack 配置中检查了:

target: "web"

我已经在导入项目中将 resolve.symlinks 设置为 false。

编辑:我已经确认它不是来自符号链接,我在 node_modules 上直接使用包时遇到完全相同的错误。

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

【问题讨论】:

所以你创建了这个组件并试图将它导入另一个 Vue 项目? @Josef7 正确。 试试看this question,听起来你需要在vue-hello-world package.json中添加一些东西,在另一个项目中作为dev依赖导入,可能使用npm link来链接包 我目前正在使用符号链接进行测试,但我确实打算在 npm 上发布它。 所以你链接到的问题不符合我的需要。 【参考方案1】:

所以我在 vue-cli repo 上提出了这个问题,我得到了解决方案! 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")

【讨论】:

【参考方案2】:

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

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

    从导入项目方面

您可以通过为导入组件的项目安装 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:不要捆绑它 - 提供 .vue 文件和源。只需将所有内容包含在模块的“src”目录中,编写一个带有解释的自述文件并完成它。让导入项目自行编译和打包。

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

【讨论】:

【参考方案3】:

不确定您是如何创建符号链接的,但您应该为此使用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 build with target lib:导入组件时“未定义要求”的主要内容,如果未能解决你的问题,请参考以下文章

[Vue] Build Vue.js Apps with the Vue-CLI and Nuxt.js

使用 vue-cli-service build --target lib 时,如何在 /dist 文件夹中复制 *.html 文件?

vue-cli-service build 比 vue ui build 更重

Build a Command Line Interface(CLI) with Node.js

vue-cli构建的项目中build后不产生.map文件的配置方法

@vue/cli3+配置build命令构建测试包&正式包