[preset-env] allow specifying corejs location

As mentioned in storybookjs/storybook#12312, we currently have a problem due to babel injecting a relative core-js import.

Inside storybook, we build from the consumer’s directory rather than storybook’s own directory (inside node_modules) which means when babel is executed, it will try import the top-level core-js.

This is a problem because the top-level core-js isn’t necessarily the same version as the one storybook has as a dependency. It can therefore cause many problems, especially if core-js 2 is imported rather than 3.

Ideally, what would be nice is the ability to specify an absolute path to core-js for babel to use when injecting paths. We could then specify the one storybook installs, explicitly.

Here:

export function getModulePath(mod: string): string {
return modulePathMap[mod] || `core-js/modules/${mod}`;
}

You blindly import core-js/modules/${mod} which is where the problem lies by the looks of it. If we could specify an absolute path which is prepended to this instead, that would solve the issue here.

I am happy to work on this if you can point me in the right direction.

Author: Fantashit

1 thought on “[preset-env] allow specifying corejs location

  1. yes basically the webpack build is executed from the user’s working directory. again using this example:

    /src
    /node_modules
    - core-js (2.x)
    - some-dependency
    -- node_modules/core-js (DEDUPED, 2.x)
    - @storybook
    -- html
    --- index.js
    --- node_modules/core-js (3.x)
    

    storybook executes webpack with inputs ["src/*", "node_modules/@storybook/whatever.js"] effectively, from / as the working directory.

    what this means is when webpack passes it through babel, babel will inject relative imports just like you said.

    but then we end up with errors like this:

    Module not found: Error: Can't resolve 'core-js/modules/web.dom-collections.iterator'
    

    because babel injected a corejs 2 import, while storybook depends on corejs 3. if we tell babel to inject 3.x imports (if thats possible), then the consumer’s code will break the same way as we’ll be trying to import a 3.x path from corejs 2.

    it seems the “ultimate solution” would be to inject the right corejs imports for each level of node_modules, so the user’s in this example would get corejs 2 imports and the storybook files would get corejs 3 imports. rather than forcing all of it to one or the other. but that sounds complex

Comments are closed.