14

I'm grokking my way through ES6 and I ran into Modules (nice!) and in learning, I am trying to see if I can use them in the browser without WebPack (which I haven't learned yet).

  1. So, I have the following files/folder structure in my JS directory

    js
    
     - lib (for complied es6 via Babel)
       - mods (compiled modules)
         - module.js (compiled via Babel)
       - app.js (imports modules, attached to index.html)
    
     - src (for "raw" es6)
       - mods (es6 modules)
         - module.js (es6 module)
       - app.js (imports modules)
    
  2. In js/src/mods/module.js, I have the following code....

    export const topTime = 1.5;
    
    export const subTime = 0.75;
    
  3. Which is imported by js/src/app.js ...

    import { topTime, subTime } from './mods/modules';
    
    console.log(topTime);
    
    console.log(subTime);
    
  4. I then compiled all es6 files to es5 (which placed the files in the lib dir.)

    npm run babel
    
  5. Now I can run the main file (js/lib/app.js) inside my editor (vscode/output tab)

    [Running] node "/home/me/www/es6.local/js/lib/app.js"
    
    1.5
    
    0.75
    

...but I think that is only because it's running in node.

  1. It breaks when I call my index.html file (with js/lib/app.js) in the browser (FF) as I get the following error...

    ReferenceError: require is not defined
    
  2. So I see that babel compiled this...

    import { topTime, subTime } from './mods/modules';
    

    into this...

    var _modules = require('./mods/modules');
    

...But I thought this was valid es5? ...no? So HOW was this done BEFORE webpack? Please advise.


Here is my package.json (in case it helps)...

{
  "name": "es6.local",
  "version": "0.0.1",
  "description": "JavaScript ES6 Testing Sandbox",
  "main": "index.html",
  "scripts": {
    "babel": "babel js/src --out-dir js/lib --source-maps"
  },
  "author": "Student",
  "license": "ISC",
  "devDependencies": {
    "eslint": "^4.16.0",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-jsx-a11y": "^6.0.3",
    "eslint-plugin-react": "^7.6.0",
    "eslint-config-airbnb": "^16.1.0",
    "babel-cli": "^6.26.0",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.6.1"
  },
  "babel": {
    "presets": [
      [
        "env",
        {
          "targets": {
            "browsers": [
              "last 2 versions",
              "safari >= 7"
            ]
          }
        }
      ]
    ]
  }
}
1
  • It may be helpful to change the accepted answer on this one Commented Mar 31, 2020 at 8:43

3 Answers 3

13

I've been stuck with this for a while and after playing around I found a solution. You don't need any libraries or webpack to do this and I'm not sure this works outside of chrome.

  1. You need to run this code on a webserver or else it won't work (in other words, it has to be on localhost, NOT file://)
  2. Make a folder called jsmodule
  3. create a file called index.html with the following code:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Js module</title>
</head>
<body>
    <h1>JS module test</h1>
    <script type="module" src="script.js"></script>
</body>
</html> 
  1. Create a file in same folder called script.js with the following code:
import Person from './Person.js';
import Book from './Book.js';


let person1 = new Person();
let someBook = new Book();
  1. create a file in same folder called Person.js with the following code:
export default class Person{
    constructor(){
        alert("hallo from person");
    }
}
  1. create a file in same folder called Book.js with the following code:
export default class Book{
    constructor(){
        alert("Hallo from book");
    }
}
  1. Run the index.html on you webserver (localhost)
Sign up to request clarification or add additional context in comments.

Comments

0

In the HTML

script src="/my-script.js" type="module">

In the script

import axios from './axios.js';

The script tag in the HTML needs to have the type of module, else the parser will not understand what import is.

The import statement needs to have the full path to the JS file you’re importing (relative paths should be fine): you cannot do import axios from 'axios' because that’s just a string — the browser has no idea if that’s even a file or where that file is.

The browser has no idea what NPM is. It’s a package manager for Node, it’s not connected to JavaScript in general. You need the actual file (which you could use NPM to add to your project, then the path will be something like ./node_modules/axios/dist/axios.js

but even using this could create some problem as it some internal dependency over some packages or libraries in node_modules folder

I would recommend using webpack or any blunder tool

which auto-magically use NPM modules then bundle everything up into a single output file.

Comments

-2

It's a pain.

exports and require are part of the CommonJS spec. If I remember correctly, webpack implements it internally. You need the same functionality, because it's not part of ES5.

Try RequireJS, or something similar to load your modules.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.