developit / microbundle

📦 Zero-configuration bundler for tiny modules.
https://npm.im/microbundle
MIT License
8.04k stars 362 forks source link

Dependencies are undefined in UMD bundle #933

Closed bugkitio closed 2 years ago

bugkitio commented 2 years ago

I've simply imported Preact into index.tsx

import { h, render } from 'preact';

export const init = () =>
  render(<main>BugKit</main>, document.getElementById('bugkit'));

And then imported the UMD bundle into my HTML file

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <div id="bugkit"></div>
    <script src="./dist/bugkit.js"></script>
    <script>
      bugkit.init();
    </script>
  </body>
</html>

I get the following console error

Uncaught TypeError: Cannot read properties of undefined (reading 'render')
    at Object.e.init (bugkit.js:1:246)
    at index.html:11:14

Init is definitely working because if I make it return a console.log, it logs out fine

Here's my package.json

{
  "name": "bugkit",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "source": "./src/index.tsx",
  "unpkg": "./dist/bugkit.js",
  "scripts": {
    "build": "microbundle --format umd",
    "dev": "microbundle watch --format umd"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "microbundle": "^0.14.2"
  },
  "dependencies": {
    "preact": "^10.6.6"
  }
}

Any ideas on why render is undefined? Any library I install with npm results in the same issue

Here's my UMD bundle

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("preact")):"function"==typeof define&&define.amd?define(["exports","preact"],t):t((e||self).bugkit={},e.preact)}(this,function(e,t){e.init=function(){return t.render(t.h("main",null,"BugKit"),document.getElementById("bugkit"))}});
//# sourceMappingURL=bugkit.js.map

Any help would be massively appreciated

rschristian commented 2 years ago

See the --external flag in the CLI options. By default, anything specified as a dependency will not be inlined into your bundle. Instead, it should be supplied separately.

Depending on what you want to do, you can move Preact into a devDependency or make sure to import Preact as well (add another <script> tag) alongside your library.

EthianWong commented 2 years ago

See the --external flag in the CLI options. By default, anything specified as a dependency will not be inlined into your bundle. Instead, it should be supplied separately.

Depending on what you want to do, you can move Preact into a devDependency or make sure to import Preact as well (add another <script> tag) alongside your library.

I totally agree with you opinion, but I also want to know how to force bundle dependencies.

In some cases I need to provide a complete SDK to other developers, they can use CDN to reference my SDK without using any package manager.

Regards

rschristian commented 2 years ago

Opinion? As I said, you can move the package into devDependencies (--external defaults to dependencies and peerDependencies, which is outlined in the docs) in your package.json or possibly use --external none if you want no external deps.

Having a dependency doesn't mean a package manager is required -- you just add another script tag (or import) for the dependency in question.

EthianWong commented 2 years ago

Having a dependency doesn't mean a package manager is required -- you just add another script tag (or import) for the dependency in question.

I know what you mean, i just want to provide multiple ways to use my SDK. User can choose add SDK module to their project, then use package manager or script tag to add SDK dependencies. But i also want the SDK it's out of the box. Just add script tag, not need to care dependencies, bundle my module with all dependencies in one dist js

EthianWong commented 2 years ago

Oh, I just explain my mean. the solution i know is use devDependencies

rschristian commented 2 years ago

Closing this out as it should be answered.