Subscribe on changes!

@vue/reactivity contains reference to `process` global

avatar
Sep 17th 2020

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"
avatar
Sep 17th 2020

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

avatar
Sep 18th 2020

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.

avatar
Sep 18th 2020

@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

avatar
Sep 18th 2020

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.