How to install nanoid in nodejs?
Asked Answered
P

5

6

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);  
}
Pyrognostics answered 26/1, 2022 at 15:7 Comment(10)
What error do you get?Halfpint
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.Pyrognostics
add type="module" to your script tag. Check if it works?Halfpint
I already added it. Without the type="module the error message is: Cannot use import statement outside a modulePyrognostics
What version of Node.js are you using? What does your package.json file look like?Jittery
Package.json: { "dependencies": { "nanoid": "^3.2.0" } } I am using node version v16.13.2.Pyrognostics
The error message that you shared 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?Turves
I updated my questionPyrognostics
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 browserOogonium
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…Pyrognostics
O
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>
Oogonium answered 26/1, 2022 at 17:34 Comment(0)
E
9

Who has this error:

Error [ERR_REQUIRE_ESM]: ...

Authors has removed CommonJS support since [email protected]

  1. Try to use ESM module imports
  2. Or use [email protected]: npm i -S [email protected]
Entozoon answered 9/7, 2022 at 9:29 Comment(0)
O
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>
Oogonium answered 26/1, 2022 at 17:34 Comment(0)
H
1

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();
Hillari answered 26/1, 2022 at 16:35 Comment(0)
C
0

I am using this nanoid, lemme share my POC,

import {nanoid} from 'nanoid';
const id = nanoid(length).toString();
Clothesbasket answered 26/1, 2022 at 15:25 Comment(2)
I still have an import error. Cannot use import statement outside a modulePyrognostics
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 generatedClothesbasket
C
0

I'm using nanoid version 2.1.9

const nanoid = require('nanoid')
let id = nanoid(5)
Contraption answered 26/1, 2022 at 15:59 Comment(2)
try to remove type="module" on your package.jsonContraption
there is no type="module" in my package.jsonPyrognostics

© 2022 - 2024 — McMap. All rights reserved.