为什么在尝试将 Vue 作为客户端库导入后,我的 webpack 捆绑应用程序中未定义 Vue
Why is Vue undefined in my webpack-bundled app after trying to import it as a client-side library
我遇到了 2 天的问题,终于解决了。导入 Vue 和 VueRouter 在我的前端代码中给出了 undefined 。这是因为 webpack 的输出,使用 externals
属性 来加载客户端库,当你导入一个外部加载的库时检查 module.__esModule
,如果为真那么它 returns module.default
。在这种情况下,Vue.__esModule
和 VueRouter.__esModule
为真,而 Vue.default
和 VueRouter.default
未定义。我什至不确定向谁提交错误,或者我是否可以添加一些东西到 webpack.config.js 来使它像以前一样工作。可能是 Vue 在他们的全球构建中包含了 __esModule
。或者它可能是 webpack 内部的东西。
这是我的一部分 package.json
"devDependencies": {
"@babel/core": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"@vue/compiler-sfc": "^3.2.30",
"babel-loader": "^8.2.3",
"css-loader": "^6.6.0",
"mini-css-extract-plugin": "^2.5.3",
"node-sass": "^7.0.1",
"sass-loader": "^12.4.0",
"vue-loader": "^17.0.0",
"webpack": "^5.68.0",
"webpack-cli": "^4.9.2"
},
"dependencies": {
"vue": "^3.2.29"
}
和webpack.config.js
const VueLoader = require('vue-loader');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: 'production',
stats: 'errors-warnings',
entry: [
'./src/app.js',
],
output: {
filename: 'compiled.js',
path: __dirname + '/js',
},
optimization: {
minimize: true,
},
performance: {
hints: 'warning',
maxEntrypointSize: 250000, // JS output 250 kB
maxAssetSize: 250000, // CSS output 250 kB
},
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.m?js$/,
resolve: {
fullySpecified: false,
},
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {targets: '>1%'}],
],
},
},
},
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader, // add support for `import 'file.scss';` in JS
{
loader: 'css-loader',
options: {
url: false, // whether to resolve urls; leave urls in the code as written
},
},
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths: [
//__dirname + '/bower_components/bootstrap-sass/assets/stylesheets',
],
},
},
},
],
},
],
},
plugins: [
new VueLoader.VueLoaderPlugin(),
new MiniCssExtractPlugin({
// Output destination for compiled CSS
filename: '../css/compiled.css',
}),
],
};
并且 index.html 加载 Vue、VueRouter、Vuex,然后是我捆绑的 webapp:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.29/vue.runtime.global.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/4.0.2/vuex.global.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.12/vue-router.global.js"></script>
<script>console.log('healthcheck', Vue, Vuex, VueRouter);</script>
<script src="/js/compiled.js"></script>
然后在我的前端代码中,与 webpack 捆绑在一起:
import Vue from "vue";
import Vuex from "vuex";
import VueRouter from "vue-router";
console.log('client', Vue, Vuex, VueRouter);
在HTML中记录healthcheck {...} {...} {...}
然后编译的应用程序记录client undefined, {...}, undefined
(Vuex被定义因为Vuex.__esModule
未定义)
有什么想法吗?
在这里回答https://github.com/vuejs/core/issues/5380
Vue 3 仅支持命名导入,例如 import {createApp} from 'vue';
我遇到了 2 天的问题,终于解决了。导入 Vue 和 VueRouter 在我的前端代码中给出了 undefined 。这是因为 webpack 的输出,使用 externals
属性 来加载客户端库,当你导入一个外部加载的库时检查 module.__esModule
,如果为真那么它 returns module.default
。在这种情况下,Vue.__esModule
和 VueRouter.__esModule
为真,而 Vue.default
和 VueRouter.default
未定义。我什至不确定向谁提交错误,或者我是否可以添加一些东西到 webpack.config.js 来使它像以前一样工作。可能是 Vue 在他们的全球构建中包含了 __esModule
。或者它可能是 webpack 内部的东西。
这是我的一部分 package.json
"devDependencies": {
"@babel/core": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"@vue/compiler-sfc": "^3.2.30",
"babel-loader": "^8.2.3",
"css-loader": "^6.6.0",
"mini-css-extract-plugin": "^2.5.3",
"node-sass": "^7.0.1",
"sass-loader": "^12.4.0",
"vue-loader": "^17.0.0",
"webpack": "^5.68.0",
"webpack-cli": "^4.9.2"
},
"dependencies": {
"vue": "^3.2.29"
}
和webpack.config.js
const VueLoader = require('vue-loader');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: 'production',
stats: 'errors-warnings',
entry: [
'./src/app.js',
],
output: {
filename: 'compiled.js',
path: __dirname + '/js',
},
optimization: {
minimize: true,
},
performance: {
hints: 'warning',
maxEntrypointSize: 250000, // JS output 250 kB
maxAssetSize: 250000, // CSS output 250 kB
},
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.m?js$/,
resolve: {
fullySpecified: false,
},
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {targets: '>1%'}],
],
},
},
},
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader, // add support for `import 'file.scss';` in JS
{
loader: 'css-loader',
options: {
url: false, // whether to resolve urls; leave urls in the code as written
},
},
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths: [
//__dirname + '/bower_components/bootstrap-sass/assets/stylesheets',
],
},
},
},
],
},
],
},
plugins: [
new VueLoader.VueLoaderPlugin(),
new MiniCssExtractPlugin({
// Output destination for compiled CSS
filename: '../css/compiled.css',
}),
],
};
并且 index.html 加载 Vue、VueRouter、Vuex,然后是我捆绑的 webapp:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.29/vue.runtime.global.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/4.0.2/vuex.global.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.12/vue-router.global.js"></script>
<script>console.log('healthcheck', Vue, Vuex, VueRouter);</script>
<script src="/js/compiled.js"></script>
然后在我的前端代码中,与 webpack 捆绑在一起:
import Vue from "vue";
import Vuex from "vuex";
import VueRouter from "vue-router";
console.log('client', Vue, Vuex, VueRouter);
在HTML中记录healthcheck {...} {...} {...}
然后编译的应用程序记录client undefined, {...}, undefined
(Vuex被定义因为Vuex.__esModule
未定义)
有什么想法吗?
在这里回答https://github.com/vuejs/core/issues/5380
Vue 3 仅支持命名导入,例如 import {createApp} from 'vue';