@vue/reactivity contains reference to `process` global
Version
2.6.11
Reproduction link
https://jsbin.com/vobulunufe/edit?html,console,output
Steps to reproduce
Import @vue/reactivity
with any system that understands the "module"
field in package.json. This includes unpkg.com and several dev servers like es-dev-server.
For example:
import {
shallowReactive,
effect
} from 'https://unpkg.com/@vue/reactivity?module';
What is expected?
The import works
What is actually happening?
"ReferenceError: process is not defined
at https://unpkg.com/@vue/shared@3.0.0-rc.12/dist/shared.esm-bundler.js?module:387:19"
That's the one for bundlers, you need to use https://unpkg.com/@vue/reactivity@3.0.0-rc.12/dist/reactivity.esm-browser.js
Not sure if we can change anything here because we still want to keep those variables in bundlers environments
Why wouldn't https://unpkg.com/@vue/reactivity?module be expected to resolve to a version that works in browsers?
The big problem is locally though. I would expect to simply write @vue/reactivity
this to import the library:
import {shallowReactive, effect} from '@vue/reactivity';
But this fails, and there's no good way to know that I should have imported a sub-module of the package. Worse though is that once you have multiple valid modules for one "conceptual" module, you can easily run into package duplication.
For example, I write all my packages so that they work without bundlers. I would want to import a module that just works, so I write:
import {shallowReactive, effect} from '@vue/reactivity/reactivity.esm-browser.js';
...and I publish a library using this to npm.
Another library author uses Webpack for testing, and doesn't notice that the module accesses Node-only APIs on the browser and writes:
import {shallowReactive, effect} from '@vue/reactivity';
...and publishes that to npm.
Now an app that uses both libraries and it imports both dist/shared.esm-bundler.js
and reactivity.esm-browser.js
leading to unnecessary bloat. With 7 bundles inside dist/
this could be quite a lot depending on what people import.
So I think it'd be best if everyone were able to import only @vue/reactivity
and have that work everywhere, including browsers, and then tooling could alias that import to other bundles if needed/ That would greatly reduce the risk of unintentional duplication.
@justinfagnani I realized this was in the wrong repo! I transferred the issue even though I don't think we can change anything because the field in the package.json file is used by different systems (like bundlers and CDNs like unpkg)
Note that if you are building a library for Vue, you should import from vue. Creating libraries for Vue will be covered in the cookbook. I have a template that can be used to create libraries and works well with Vue: https://github.com/posva/vue-ts-lib-boilerplate.
So I think it'd be best if everyone were able to import only @vue/reactivity and have that work everywhere, including browsers, and then tooling could alias that import to other bundles if needed/ That would greatly reduce the risk of unintentional duplication.
Yeah, but that would remove a lot of benefits that exist today to improve DX while still producing a smaller bundle.
It's simply not realistic to expecta library to be built only for esm browser usage, even though you are free to do so. That's why I created the boilerplate, I know it's hard to manage
In addition to the dev-only code (warnings and edge case checks), the esm-bundler
distribution format also contains the ability to expose compile-time feature flags (tree-shakes features when flags are disabled), which is impossible in browser-oriented builds. This is important because Vue as a framework has a lot of features that may or may not end up getting used, and having a separate ESM distribution targeting bundlers is necessary for getting the maximum benefits from tree-shaking.