developit / microbundle

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

Error when using file JS built by microbundle "Uncaught ReferenceError: require is not defined" #1078

Closed yenle16 closed 1 month ago

yenle16 commented 2 months ago

Hi, This is part of my package.json to use microbundle build 1 preact widget

  "source": "src/index.ts",
  "main": "dist/index.js",
  "module": "dist/index.module.js",
  "umd:main": "dist/index.umd.js",
  "scripts": {
    "dev": "preact watch",
    "build:widget": "microbundle build --css inline --format cjs --no-sourcemap",
    "build:lib": "microbundle build -i src/component.js --sourcemap=false",
    "lint": "eslint '{src,test}/**/*.js'",
    "test": "jest"
  },

As a result, I get an index.js file in the dist folder, I use it to embed my page with a script tag <script type="module" id="embed-form" src="/dist/index.js"></script>

Browser console error '(Uncaught ReferenceError: require is not defined)' Do you have a solution for that ?

rschristian commented 2 months ago

Hey, thanks for popping over here, it's a bit easier to answer in full.

As mentioned, CJS is not suitable for browser use. You want the UMD, ESM, or Modern bundles for this. It seems this is what you want to do anyhow, as you're adding type="module" to your script tag.


Edit: Here's a demo: https://github.com/rschristian/demo__microbundle-preact-widget, certainly let me know if you have any questions on any part of it

yenle16 commented 2 months ago

Thank you, maybe I have solved the above error, but there is another problem I have, I am using .env variables and the current browser cannot read it 'Uncaught ReferenceError: process is not defined' Maybe it's a mistake in setting up my build, do you know why?

rschristian commented 2 months ago

Indeed. process too only exists in Node, so if you want Microbundle to swap our your variables, you need to tell it to do so with the --define flag. For example:

// input
console.log(process.env.MY_VAR);

$ microbundle --define process.env.MY_VAR="hello world!"

// output
console.log("hello world!");
yenle16 commented 2 months ago

Really, I think environment variables should be bind, and seems like my tailwindcss is not bundled

rschristian commented 2 months ago

I don't really have much of an opinion either way, but this is the way env vars work for now anyways.

Did you follow the example I gave for importing CSS? I'll need more info to go on as, as my demo shows, it's working as intended.

rschristian commented 2 months ago

Are you importing your built Tailwind CSS like import styles from './built-tailwind.css'? We won't compile your Tailwind for you, so that needs to be available before Microbundle runs.

Additionally, Tailwind produces quite large outputs, keep in mind that this will bloat your bundles by a non-negligible amount.

yenle16 commented 2 months ago

I use Tailwind to css, and when I build and use it but my tailwind classes don't work, Do you have a solution for that ? image

rschristian commented 2 months ago

You need to provide a reproduction, "my tailwind classes don't work" isn't enough information for me to offer any real help unfortunately.

Are you creating a <style> tag w/ your CSS string? Are you inserting it into the document? Like this or similar?

yenle16 commented 2 months ago

It's hard for you if I keep asking around, this is my repo and everything I configure is here, you can see how I'm doing https://github.com/yenle16/demo__signupform

rschristian commented 2 months ago

This won't work. You need to do it as I've done.

rschristian commented 2 months ago

That's just TypeScript, you can ignore it with a // @ts-ignore comment like this:

// @ts-ignore
import styles from './style.css';

or add an ambient declaration file like this:

// src/global.d.ts
declare module '*.css' {
    const css: string;
    export default cssl;
}

Totally unrelated to Microbundle.


import './style.css', as you have done, is what's called a side-effectful import. This is fine if you're using a CSS loader as you might in a web app, but when we're trying to inline the CSS, this essentially does nothing at all. You're trying to import something, but not using it, so the bundler (correctly) throws it away. That's why we need import styles from './style.css'

yenle16 commented 1 month ago

Indeed. process too only exists in Node, so if you want Microbundle to swap our your variables, you need to tell it to do so with the --define flag. For example:

// input
console.log(process.env.MY_VAR);

$ microbundle --define process.env.MY_VAR="hello world!"

// output
console.log("hello world!");

Can you help me with this problem, if I have 2 env variables how can I define them with --define flag

rschristian commented 1 month ago

Use a comma to separate them, e.g.:

$ microbundle --define process.env.MY_VAR="hello world!",foo="bar"

yenle16 commented 1 month ago

"dev": "microbundle watch --no-sourcemap --external none --define process.env.PREACT_APP_API_URL='xxx',process.env.PREACT_APP_DOMAIN_URL ='yyy'", i tried it before with this script, but it didn't work

rschristian commented 1 month ago

I can't reproduce, that works just fine for me.

Here's a demo: https://github.com/rschristian/demo__microbundle-define

yenle16 commented 1 month ago

Many thanks for helping me, I did it

rschristian commented 1 month ago

I'll close this out in that case, but feel free to reply here or open a new issue if you continue to have any problems.