简体   繁体   中英

Using Modules in the Browser (without WebPack)

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"
            ]
          }
        }
      ]
    ]
  }
}

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)

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM