ESM is the normalized way for module function in Javascript. But there are many CommonJs package in npm. Vite is good tools for change CommonJs to ESM, I want to use protobufjs in a vue project. The protobufjs in: https://github.com/protobufjs/protobuf.js/
It works in npm run dev
. I want to build it for production environment, following the guide in: https://cn.vitejs.dev/config/build-options.html#build-commonjsoptions
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import commonjs from '@rollup/plugin-commonjs'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
commonjs({
include: /node_modules/,
}),
vue(),
]
})
I use it in vue as following:
<script setup>
import * as protobuf from "protobufjs";
console.log(protobuf.Enum)
</script>
Everything is ok when I run the npm run dev
. I occurs error in npm run build
:
src/App.vue (13:21): "Enum" is not exported by "node_modules/.pnpm/protobufjs@7.4.0/node_modules/protobufjs/index.js", imported by "
src/App.vue".
The example is simple, and config is also. But what result in the error?
Vite is a simple tool to use CommonJs, UMD or AMD modules in ESM. It use esbuild in dev
and @rollup/plugin-commonjs
in prod
by default. So we needn't do the config it explicitly.
Thanks for @Estus Flask
a lot.
CommonJS modules aren't recognized in ESM environment and require additional module interoperation to work, such as @rollup/plugin-commonjs
in Vite/Rollup build. Since Vite has different toolchains for dev
and build
, there can be discrepancies.
The "universal" way is to use default import. It's less natural for CJS to be translated to *
because the export is dynamic, it cannot use ESM traits such as tree-shaking, and can be not just an object but anything.
This is defined by defaultIsModuleExports
option, which can be changed if necessary. Transpiled ES modules are automatically recognized by default, this is commonly determined with __esModule
property in module object.
Since protobufjs
is CJS/UMD module depending on entry point and not transpiled ESM, the correct way to use it:
import protobuf from "protobufjs";
It may be desirable to map entry point to UMD bundle for performance, with the same result expected:
alias: { ..., protobufjs: "protobufjs/dist/protobuf.min.js" }
@rollup/plugin-commonjs
isn't needed to be explicitly configured, it's already provided with suitable configuration in Vite default configuration.