vite 在开发和生产中是否对模块导入进行了不同的处理?
Are module imports treated differently by vite in development and production?
我正在尝试将库 (jointjs) 导入 Vue 应用程序。它在 Vue 上被分配为全局 属性 并随后被修改。这是我正在尝试做的事情的简单再现:
import Vue from 'vue';
import * as joint from 'jointjs';
import App from '@/App.vue';
// we need to get our own connectors
let customConnectors={
f: function() {}
}
Vue.use({
install: function (Vue) {
// In development, this works:
// _.assign(joint.connectors, customConnectors);
// as does this:
// _.each(customConnectors, (item, key) => { joint.connectors[key] = item;});
// and this:
// for (const connector in customConnectors) {
// joint.connectors[connector] = customConnectors[connector];
// }
// but none of those work in production, saying joint is a constant or not extensible
// this one gives a build error about f not being exported by jointjs/src/connectors
// joint.connectors['f'] = customConnectors['f'];
// this one gives the same error but runs without error; but only when minified, so I think it's actually
// just removing the statement
joint.connectors.f = customConnectors.f;
Vue.joint = joint;
}
});
let app = new Vue({
joint,
render: h => h(App)
}).$mount('#app');
上面评论中的每个示例在开发中都可以正常工作。 None 它们在为生产而构建时工作。
问题似乎出在生产中,jointjs 的导入被视为常量,但在开发中却不是?
这是我的vite配置:
import { defineConfig } from 'vite';
import { createVuePlugin } from 'vite-plugin-vue2';
import ViteComponents from 'vite-plugin-components';
import path from 'path';
export default defineConfig({
plugins: [
createVuePlugin(),
ViteComponents({
})
],
server: {
port: 8080
},
resolve: {
alias: [
{
find: '@',
replacement: path.resolve(__dirname, 'src')
}
]
},
build: {
chunkSizeWarningLimit: 600,
}
});
这是故意的行为吗?我缺少构建选项吗?
如果有帮助的话,这里是一个复制回购协议:https://github.com/dovrosenberg/vite-test
谢谢!
感谢评论中 Estus Flask 的提示,我成功完成了这项工作。
我先用rollup把jointjs转成了ES模块
npm i --save-dev rollup-plugin-commonjs
应该已经安装了 Rollup,因为 vite 使用它。
我在项目根目录下创建了一个rollup.config.js文件:
import commonjs from 'rollup-plugin-commonjs';
export default {
input: 'node_modules/jointjs/joint.mjs',
output: {
file: 'src/plugins/jointjsESM.js',
format: 'es',
freeze: false, // this is key to preventing everything from being constant
},
plugins: [
commonjs({
// search for files other than .js files (must already
// be transpiled by a previous plugin!)
extensions: [ '.js', '.mjs' ], // Default: [ '.js' ]
// if true then uses of `global` won't be dealt with by this plugin
ignoreGlobal: false, // Default: false
// if false then skip sourceMap generation for CommonJS modules
sourceMap: false, // Default: true
}),
],
};
output.file
值可以指向您希望生成的模块所在的位置。
然后您可以创建 package.json 脚本(或使用 npx)到 运行 rollup --config rollup.config.js
这将在 output.file 位置创建新的模块文件。您可以 运行 在 vite 构建之前将此脚本作为构建管道的一部分。
然后,您从输出的文件中导入而不是 import * as joint from 'jointjs'
,但是您需要使用您需要的任何部分自己 assemble 联合对象...例如:
import {
g,
dia,
shapes,
connectors,
} from '@/plugins/jointjsESM.js';
let joint = { g, dia, shapes, connectors};
您还可以将 jointjs 移动为仅作为开发依赖项安装,因为它不会用作构建的一部分。
我正在尝试将库 (jointjs) 导入 Vue 应用程序。它在 Vue 上被分配为全局 属性 并随后被修改。这是我正在尝试做的事情的简单再现:
import Vue from 'vue';
import * as joint from 'jointjs';
import App from '@/App.vue';
// we need to get our own connectors
let customConnectors={
f: function() {}
}
Vue.use({
install: function (Vue) {
// In development, this works:
// _.assign(joint.connectors, customConnectors);
// as does this:
// _.each(customConnectors, (item, key) => { joint.connectors[key] = item;});
// and this:
// for (const connector in customConnectors) {
// joint.connectors[connector] = customConnectors[connector];
// }
// but none of those work in production, saying joint is a constant or not extensible
// this one gives a build error about f not being exported by jointjs/src/connectors
// joint.connectors['f'] = customConnectors['f'];
// this one gives the same error but runs without error; but only when minified, so I think it's actually
// just removing the statement
joint.connectors.f = customConnectors.f;
Vue.joint = joint;
}
});
let app = new Vue({
joint,
render: h => h(App)
}).$mount('#app');
上面评论中的每个示例在开发中都可以正常工作。 None 它们在为生产而构建时工作。
问题似乎出在生产中,jointjs 的导入被视为常量,但在开发中却不是?
这是我的vite配置:
import { defineConfig } from 'vite';
import { createVuePlugin } from 'vite-plugin-vue2';
import ViteComponents from 'vite-plugin-components';
import path from 'path';
export default defineConfig({
plugins: [
createVuePlugin(),
ViteComponents({
})
],
server: {
port: 8080
},
resolve: {
alias: [
{
find: '@',
replacement: path.resolve(__dirname, 'src')
}
]
},
build: {
chunkSizeWarningLimit: 600,
}
});
这是故意的行为吗?我缺少构建选项吗?
如果有帮助的话,这里是一个复制回购协议:https://github.com/dovrosenberg/vite-test
谢谢!
感谢评论中 Estus Flask 的提示,我成功完成了这项工作。
我先用rollup把jointjs转成了ES模块
npm i --save-dev rollup-plugin-commonjs
应该已经安装了 Rollup,因为 vite 使用它。
我在项目根目录下创建了一个rollup.config.js文件:
import commonjs from 'rollup-plugin-commonjs';
export default {
input: 'node_modules/jointjs/joint.mjs',
output: {
file: 'src/plugins/jointjsESM.js',
format: 'es',
freeze: false, // this is key to preventing everything from being constant
},
plugins: [
commonjs({
// search for files other than .js files (must already
// be transpiled by a previous plugin!)
extensions: [ '.js', '.mjs' ], // Default: [ '.js' ]
// if true then uses of `global` won't be dealt with by this plugin
ignoreGlobal: false, // Default: false
// if false then skip sourceMap generation for CommonJS modules
sourceMap: false, // Default: true
}),
],
};
output.file
值可以指向您希望生成的模块所在的位置。
然后您可以创建 package.json 脚本(或使用 npx)到 运行 rollup --config rollup.config.js
这将在 output.file 位置创建新的模块文件。您可以 运行 在 vite 构建之前将此脚本作为构建管道的一部分。
然后,您从输出的文件中导入而不是 import * as joint from 'jointjs'
,但是您需要使用您需要的任何部分自己 assemble 联合对象...例如:
import {
g,
dia,
shapes,
connectors,
} from '@/plugins/jointjsESM.js';
let joint = { g, dia, shapes, connectors};
您还可以将 jointjs 移动为仅作为开发依赖项安装,因为它不会用作构建的一部分。