Skip to content

How to get unbundled cjs/es modules as in version 0.4.4? #514

Description

@gamtiq

First of all I would like to thank for the excellent tool!

Before version 0.5.0, building with cjs and es format produced unbundled modules with required/imported dependencies (i.e. output of entry modules didn’t contain code of its dependencies).
Is it possible to get the same result in the current version (0.11.0)?

Activity

  1. ForsakenHarmony commented on Nov 8, 2019

    @ForsakenHarmony
    Collaborator

    You dependencies should not get bundled

    Which command are you running to build(/bundle) your library?

  2. tunnckoCore commented on Nov 9, 2019

    @tunnckoCore

    @gamtiq 0.4.4? That's pretty old at first and it probably was wrong behvaior.

    Anyway, you should be able to use --external (comma-separated list) for this, or just add them in dependencies or peerDependencies. It's general practice when you want to bundle them to put them in devDepdendecies, since most similar tools automatically get deps and peerDeps and put them as "external" (so they won't get bundled).

  3. developit commented on Nov 9, 2019

    @developit
    Owner

    Yup! devDependencies get bundled, dependencies & peerDependencies don't.

  4. tunnckoCore commented on Nov 9, 2019

    @tunnckoCore

    devDependencies get bundled

    It's not exactly correct to say that. You get bundled the dependencies that your code uses - unless they are in deps & peerDeps, it's not bundling all devDeps. You can put your dependencies wherever you want - e.g. optionalDependencies.

    Anyway, just a bit clarification for total newcommers.

  5. gamtiq commented on Nov 9, 2019

    @gamtiq
    Author

    The talk is about local dependencies (not from npm).
    The following example should clarify the case.

    Source code

    package.json

    {
      "name": "some-lib",
      "version": "1.0.0",
      "main": "src/index.js",
      "scripts": {
        "build-commonjs": "microbundle build \"src/*.js\" --output dist/commonjs --format cjs --strict --no-compress",
        "build-esm": "microbundle build \"src/*.js\" --output dist/es-module --format es --no-compress"
      },
      "devDependencies": {
        "microbundle": "0.11.0"
      }
    }

    src/a.js

    export function a() {
    }

    src/index.js

    import { a } from './a';
    
    export function b() {
        return a();
    }

    Result for microbundle 0.4.4

    After running npm run build-commonjs you have got the following output.

    dist/commonjs/a.js

    'use strict';
    
    function a() {}
    
    exports.a = a;
    //# sourceMappingURL=a.js.map

    dist/commonjs/some-lib.js

    'use strict';
    
    var a_js = require('./a.js');
    
    function b() {
        return a_js.a();
    }
    
    exports.b = b;
    //# sourceMappingURL=some-lib.js.map

    You can see that local dependency is not bundled but imported.
    The same is true for npm run build-esm.

    Result for microbundle 0.11.0

    After running npm run build-commonjs you have got the following output.

    dist/commonjs/a.js

    'use strict';
    
    function a() {}
    
    exports.a = a;
    //# sourceMappingURL=a.js.map

    dist/commonjs/some-lib.js

    'use strict';
    
    function a() {}
    
    function b() {
      return a();
    }
    
    exports.b = b;
    //# sourceMappingURL=some-lib.js.map

    You can see that dependency from a.js is bundled into some-lib.js.
    The same is true for npm run build-esm.

    Versions 0.5.0+ have similar output.

    Is it possible to get for current version of microbundle the same result as for version 0.4.4?

  6. tunnckoCore commented on Nov 9, 2019

    @tunnckoCore

    Don't think so.

    That totally not making sense to me, sorry. Seems like bug in that 0.4.4 version I guess.

    What you want is not bundling but building, so you can just use Babel for this which outputs the same file structure but transpiled.

    Why would you want such output? Why would you use microbundle or anything built on top of Rollup or Webpack when you don't want everything to be bundled in one file?

    Recent versions of Rollup support that though (or similar thing, didn't tried it yet) with preserveModules, but I don't see the point at all.

  7. Andarist commented on Nov 9, 2019

    @Andarist
    Collaborator

    One reason for preserveModukes is to still benefit from tree shaking and rollup plugin processing. The use case is niche but it is there.

    Other thing than preserveModules is ability to output multiple entry files - and the use case for this is to bundle everything as flat as possible, but create multiple public entry points with code shared between them by automatically created chunks. It exposes what we want to be public, but hides everything that is supposed to be private

  8. gamtiq commented on Nov 9, 2019

    @gamtiq
    Author

    Why would you want such output? Why would you use microbundle or anything built on top of Rollup or Webpack when you don't want everything to be bundled in one file?

    The short answer is simplicity.
    microbundle allows to bypass complex configuration of build tools (e.g. Babel, Rollup, webpack etc).
    For me the behavior of version 0.4.4 makes sense. Using one tool (microbundle) I can get transpiled but not bundled CommonJS and ESM builds and bundled UMD build.

  9. ForsakenHarmony commented on Nov 9, 2019

    @ForsakenHarmony
    Collaborator

    if you don't want bundling you might just want to use babel with babel-preset-env

  10. Andarist commented on Nov 9, 2019

    @Andarist
    Collaborator

    @ForsakenHarmony this would force @gamtiq to create multiple babel tasks (1 for ESM, 1 for CJS) and he'd still probably have to use rollup/microbundle to output UMD. Gains from using microbundle in this case are questionable - but it's nice to have a single tool that can do its job with 0 config.

    But even besides that, there are reasons for bundling into multiple entry points. https://preconstruct.tools/guides/when-should-i-use-multiple-entrypoints

    For example in emotion we have 2 entry points for one of packages - @emotion/styled and @emotion/styled/base. This is because that main entry looks like this:
    https://unpkg.com/browse/@emotion/styled@11.0.0-next.3/dist/styled.browser.esm.js

    It just adds some convenience stuff onto /base entry - but with a babel plugin we actually rewrite imports and call sites to use that /base directly.

    In this particular example benefits of using rollup are not as apparent, but in the case of redux-saga becomes more clear:
    https://unpkg.com/browse/@redux-saga/core@1.1.3/dist/
    There are 2 entry points - redux-saga and redux-saga/effects - and they share common (private) code which gets put into auto-generated chunks (those io-*.js in here).

  11. ForsakenHarmony commented on Nov 10, 2019

    @ForsakenHarmony
    Collaborator

    If it's just about having multiple entrypoints, you can currently do that

    We have it setup for microbundle itself

    https://github.com/developit/microbundle/blob/master/package.json#L11

    (but I guess that's cjs only, I'm not entirely sure how well it works with multiple formats)

  12. tunnckoCore commented on Nov 10, 2019

    @tunnckoCore

    The thing is that all this is already totally different behavior and new feature to comment (not bundling at all even local deps).

    I'm guessing that @gamtiq can currently do --external ./a.js and for all other local files. It's a bit to much but... that's for now.

  13. marvinhagemeister commented on Nov 10, 2019

    @marvinhagemeister
    Collaborator

    Reading the through comments here, it sounds very much like microbundle doesn't fit into the problem space the original poster is looking for. microbundle originated from the preact repo where we were looking for ways to make our customized build pipeline reusable. As the name microbundle implies we do bundle the code for performance reasons for preact.

    Supporting non-bundled code is a non-trivial task. My understanding is that there may have been some accidental behavior like that possible in a very early version. As far as I'm aware it was not a planned feature, hence the reliance on a bundler like rollup at the core.

    Nonetheless it's an interesting use case. I'm sure the team is happy to review any PRs or give guidance of the code in this repo if needed. I don't think it makes much sense for the microbundle team to work on that, because it's just a thin wrapper around rollup with some pre-configured plugins. If rollup or some plugin allows for such a feature to be easily implemented, it would be worth to check that out.

  14. 3 remaining items

  15. tunnckoCore commented on Nov 11, 2019

    @tunnckoCore

    Ooh, i just spot the difference between the commands - in first there is input passed (glob pattern), and in the second there isn't input. Can you (i can check later) in the source code of it how the no input case was handled.

    I'm guessing the result of the first command (with glob pattern, more specifically a globstar) was exactly because the glob pattern. What's the result now since it is still supporting multiple entrypoints like microbundle itself is doing ({index,cli}.js)

  16. tunnckoCore commented on Nov 11, 2019

    @tunnckoCore

    @gamtiq interesting enough, it works for me as you expect in both 0.4.4 and the latest.

    With all possible variants:

    # not bundled (0.4.4 and latest)
    microbundle build 'src/*.js' --format cjs,es --no-compress
    
    # not bundled (0.4.4 and latest)
    microbundle build 'src/{index,add}.js' --format cjs,es --no-compress
    
    # bundled (0.4.4 and latest)
    microbundle build --format cjs,es --no-compress
    

    https://github.com/tunnckoCore/mb-issue-514

    Still possible. And yet, i still think it's incorrect behavior.

  17. gamtiq commented on Nov 12, 2019

    @gamtiq
    Author

    I've checked https://github.com/tunnckoCore/mb-issue-514 and cannot get not bundled build for latest microbundle (0.11.0).
    After running
    npx microbundle build "src/*.js" --format cjs,es --no-compress --output dist/build-1
    or
    npx microbundle build "src/{index,add}.js" --format cjs,es --no-compress --output dist/build-2
    I have got the following output for index.js

    function add(a, b) {
      return a + b;
    }
    
    function bar() {
      return add(1, 2);
    }
    
    exports.bar = bar;
    //# sourceMappingURL=mb-issue-514.js.map

    Perhaps the issue depends on environment.
    My environment is the following: Windows 7, node 10.15.3, npm 6.4.1.

  18. tunnckoCore commented on Nov 13, 2019

    @tunnckoCore

    Oh, of course. Are you using the Windows prompt or using something like git bash or github desktop or..? I don't know. I don't think Windows support globs and that's the problem. Unbundled to work, the input need to be some glob pattern (*.js or {}) instead of actual file.

    Now I see and understand why issue templates are good idea :D

  19. gamtiq commented on Nov 14, 2019

    @gamtiq
    Author

    I can confirm that the issue is specific to Windows.
    I can get not bundled build by microbundle 0.11.0 on macOS with node 10.15.3 and npm 6.4.1.

  20. ForsakenHarmony commented on Nov 14, 2019

    @ForsakenHarmony
    Collaborator

    Does it matter if you put the build step in an npm script instead of running it directly?

    And with or without quotes, see https://github.com/developit/microbundle/blob/master/package.json#L11

  21. gamtiq commented on Nov 16, 2019

    @gamtiq
    Author

    It doesn't matter whether a build is started by npx or by a npm script. The result is the same: bundled code.
    I've tried the following variants of npm scripts:

    • microbundle build --format cjs --no-compress --output dist/build-1 src/*.js
    • microbundle build --target=node --format cjs --no-compress --output dist/build-1 src/*.js
    • microbundle build --format cjs --no-compress --output dist/build-2 src/{index,add}.js
    • microbundle build --target=node --format cjs --no-compress --output dist/build-2 src/{index,add}.js
  22. tunnckoCore commented on Nov 16, 2019

    @tunnckoCore

    Flags doesn't matter. The problem is in globbing.

    Try 'src/*.js' and 'src/{index,add}.js'. This way the glob will be passed directly to the microbundle not expanded by the terminal.

  23. gamtiq commented on Nov 17, 2019

    @gamtiq
    Author

    Usage of single quotes in npm script

      "scripts": {
        "build-1": "microbundle build --format cjs --no-compress --output dist/build-1 'src/*.js'"
      }

    results in the following error:

    > microbundle build --format cjs --no-compress --output dist/build-1 'src/*.js'
    
    WARN missing package.json "name" field. Assuming "mb-issue-514".
    Error: ENOENT: no such file or directory, scandir ''src'
    
        at Object.readdirSync (fs.js:785:3)
        at walk (mb-issue-514\node_modules\tiny-glob\sync.js:12:20)
        at module.exports (mb-issue-514\node_modules\tiny-glob\sync.js:78:3)
        at mb-issue-514\node_modules\microbundle\dist\microbundle.js:327:97
        at Array.map (<anonymous>)
        at _temp4 (mb-issue-514\node_modules\microbundle\dist\microbundle.js:327:68)
        at _temp5 (mb-issue-514\node_modules\microbundle\dist\microbundle.js:332:46)
        at _temp6 (mb-issue-514\node_modules\microbundle\dist\microbundle.js:335:44)
        at getInput (mb-issue-514\node_modules\microbundle\dist\microbundle.js:344:47)
        at mb-issue-514\node_modules\microbundle\dist\microbundle.js:433:30

    Similar error is for './src/*.js':
    Error: ENOENT: no such file or directory, scandir ''.\src'

  24. tunnckoCore commented on Nov 17, 2019

    @tunnckoCore

    Interesting. Hm so, microbundle is doing something interesting. I'll check later.

  25. added a commit that references this issue on Apr 19, 2020
    d50bd14
  26. added
    has-fixA fix is available, but may not yet be released.
    on Dec 18, 2020
  27. developit commented on Dec 18, 2020

    @developit
    Owner

    Unless someone comments, I'm going to assume this is fixed in 0.12 / 0.13. Please re-open if not.

  28. gamtiq commented on Dec 22, 2020

    @gamtiq
    Author

    Unfortunately the issue takes place in version 0.13.
    See gamtiq/microbundle-issue-514 to reproduce.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    has-fixA fix is available, but may not yet be released.needs more infoNeeds more informationquestion ❔

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions