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
知道发生了什么吗?
备注:
- 使用
vue inspect
,我在 webpack 配置中检查了:
target: "web"
- 我已经在导入项目中将 resolve.symlinks 设置为 false。
编辑:我已经确认它不是来自符号 link,我直接在 node_modules.
上的包有完全相同的错误
不确定您是如何创建符号 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" 字段所述。所以问题在于尝试导入的项目,而不是导出组件的项目。
有两种方法可以尝试解决这个问题。
- 来自导入项目方
您可以通过为导入您的组件的项目安装 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 插件的 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")
我正在尝试将 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
知道发生了什么吗?
备注:
- 使用
vue inspect
,我在 webpack 配置中检查了:
target: "web"
- 我已经在导入项目中将 resolve.symlinks 设置为 false。
编辑:我已经确认它不是来自符号 link,我直接在 node_modules.
上的包有完全相同的错误不确定您是如何创建符号 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" 字段所述。所以问题在于尝试导入的项目,而不是导出组件的项目。
有两种方法可以尝试解决这个问题。
- 来自导入项目方
您可以通过为导入您的组件的项目安装 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 插件的 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")