3

I am currently trying to import and use nanoid in my (Firebase) nodejs project. I installed it with

npm i nanoid

and I tried to import it with

import { nanoid } from 'nanoid'

and

import { nanoid } from '../node_modules/nanoid/nanoid.js'

Everything I tried failed. I am a complete beginner with nodejs and js itself, but no Website or Documentation helped me fixing the problem. I just want an unique id :(

heres my index.html (reduced to minimum:

<!DOCTYPE html>
<html>
  <head>
    <title>Welcome to Firebase Hosting</title>

    !!!Here are Firebase imports!!!
 
    <script defer src="/__/firebase/init.js?useEmulator=true"></script>
    <link rel="stylesheet" href="style.css">


  </head>
  <body>

    <div class="registerContainer">

    <div class="registerContent">
    <h1 id="title">Sign up</h1>
    <iframe name="hiddenFrame" width="0" height="0" border="0" style="display: none;"></iframe>
    <form id="form" onsubmit="return false">
    


      <!-- Birth date Input (required) -->
      <div class="input_field">
          <input id="date" onfocus="(this.type = 'date')" class="text_input" type="text" name="birthdate" placeholder="Geburtsdatum" required />
      </div>

      <!-- Checkbox 1 -->
      <div class="input_field checkbox_option">
          <input type="checkbox" id="cb1" class="checkbox">
          <label for="cb1">I agree with terms and conditions</label>
      </div>


      <input class="button" id="registerUser" type="submit" value="Anmelden"/>

    </form>
  </div>
    </div>

    <script src="app.js"></script>

  </body>
</html>

app.js:

const nanoid = require('nanoid');

document.addEventListener('DOMContentLoaded', event => {
    const app = firebase.app();
    const db = firebase.firestore();

    const users = db.collection('users');
})


async function addUser() {
    console.log('adding User');
    const db = firebase.firestore();
    const users = db.collection('users');   
    const data = {
        email: document.getElementById("email").value,
        test_active: false
    };

    
    code = nanoid(10).toString();
    await users.doc(code).set(data);  
}
Linus Grosser
  • 103
  • 1
  • 1
  • 8
  • What error do you get? – Gnanavel Jan 26 '22 at 15:11
  • `Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.` – Linus Grosser Jan 26 '22 at 15:14
  • add `type="module"` to your script tag. Check if it works? – Gnanavel Jan 26 '22 at 15:20
  • I already added it. Without the `type="module` the error message is: `Cannot use import statement outside a module` – Linus Grosser Jan 26 '22 at 15:32
  • What version of Node.js are you using? What does your `package.json` file look like? – Zulfe Jan 26 '22 at 16:05
  • Package.json: `{ "dependencies": { "nanoid": "^3.2.0" } }` I am using node version v16.13.2. – Linus Grosser Jan 26 '22 at 16:10
  • The [error message that you shared](https://stackoverflow.com/questions/70865639/how-to-install-nanoid-in-nodejs#comment125279391_70865639) suggests that it came from a browser's dev tools console. Can you share a link to your project's source files (e.g. on GitHub) or include the contents of them in your question? – jsejcksn Jan 26 '22 at 16:20
  • I updated my question – Linus Grosser Jan 26 '22 at 16:28
  • Are you using browserify? Otherwise it looks like your code is meant to run on the browser and the `require` function doesn't exist in the browser – Abir Taheer Jan 26 '22 at 16:53
  • I don’t know what „browserify“ is, but Yes, the program is running on the browser, since it’s a website. I thought nodejs is for the web only… – Linus Grosser Jan 26 '22 at 17:00

5 Answers5

7

Who has this error:

Error [ERR_REQUIRE_ESM]: ...

Authors has removed CommonJS support since nanoid@4.0.0

  1. Try to use ESM module imports
  2. Or use nanoid@3.0.0: npm i -S nanoid@3.0.0
zemil
  • 3,235
  • 2
  • 24
  • 33
3

Based on your existing comments it appears that you're running this code in the browser and you also don't have browserify or any other bundler in your project.

That conclusion came from the fact that you commented that you got the error

require is not defined

require is a function specific to server side NodeJS projects and doesn't exist in the browser. If you want to use the require function you need to use a bundler like browserify or webpack that will fetch the relevant packages from your node_modules folder and bundle them together for your front-end to use.

The reason you're getting the

Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.

error is because when you ask javascript to run the following:

import {nanoid} from 'nanoid';

what the browser thinks is that the directory containing the current page also has a file called nanoid and is making a request for that file.

Consider the following: If my page is at https://google.com and my code says import {nanoid} from 'nanoid' the browser is going to make a request to https://google.com/nanoid and the browser is expecting a javascript file but it's likely receiving an error 404 html page.

Remember, the browser does not have access to your node_modules folder unless it's publicly exposed on your webserver and in that situation you need to tell it the exact path to the file you're trying to import.

What can you do?

You can add webpack or browserify or some other bundler to your project but that might require a bit of work and you mentioned you're a beginner so I don't think it'd be a good idea to jump right in.

The other option might be to add the browser version of the nanoid code directly into your own project.

I've taken the browser version of the code from the github https://github.com/ai/nanoid/blob/main/index.browser.js and put it into a script tag (getting rid of the urlAlphabet import) below that you can add to your code. Keep in mind this code will add the nanoid, customAlphabet, customRandom, urlAlphabet, and random variables globally so make sure there aren't any collisions with your global variables.

<!-- Code for nanoid directly from the github with urlAlphabet import removed -->
<!-- https://github.com/ai/nanoid/blob/main/index.browser.js -->
<script>
let urlAlphabet =
  'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'
let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))
let customRandom = (alphabet, size, getRandom) => {
  let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
  let step = -~((1.6 * mask * size) / alphabet.length)
  return () => {
    let id = ''
    while (true) {
      let bytes = getRandom(step)
      let j = step
      while (j--) {
        id += alphabet[bytes[j] & mask] || ''
        if (id.length === size) return id
      }
    }
  }
}
let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random)
let nanoid = (size = 21) => {
  let id = ''
  let bytes = crypto.getRandomValues(new Uint8Array(size))
  while (size--) {
    let byte = bytes[size] & 63
    if (byte < 36) {
      // `0-9a-z`
      id += byte.toString(36)
    } else if (byte < 62) {
      // `A-Z`
      id += (byte - 26).toString(36).toUpperCase()
    } else if (byte < 63) {
      id += '_'
    } else {
      id += '-'
    }
  }
  return id
}
</script>

<p id="code"></p>

<!-- You can now use the nanoid() function in your javascript code -->
<script>
const id = nanoid();

document.getElementById("code").innerHTML = id;
</script>
Abir Taheer
  • 2,502
  • 3
  • 12
  • 34
  • Dear Abir, you are a real hero. Thank you for taking the time to help me find the solution. I am really happy that this now works, and thank you for all the tips. Linus – Linus Grosser Jan 26 '22 at 18:44
0

I am using this nanoid, lemme share my POC,

import {nanoid} from 'nanoid';
const id = nanoid(length).toString();
Vijay
  • 228
  • 3
  • 8
  • 1
    I still have an import error. `Cannot use import statement outside a module` – Linus Grosser Jan 26 '22 at 15:34
  • which means you should not import like this instead like below, const nanoid = require('nanoid').nanoid; const id = nanoid(8).toString() // 8 characters will be generated – Vijay Jan 27 '22 at 17:26
0

I'm using nanoid version 2.1.9

const nanoid = require('nanoid')
let id = nanoid(5)
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
0

Try adding rounded brackets around as such { nanoid } before requiring it and then declaring a var named ID to store it :

var { nanoid } = require('nanoid');

var ID = nanoid();