Search code examples
javascriptnode.jswebpackbabel-loader

browser throw error of export/import keyword even webpack and babel is installed


I am developing a very basic and simple app with core javascript and html I have installed webpack v 4 and start server using

npm run webpack

the project compiled successfully; below is the output

> canvas@1.0.0 webpack /opt/parixan/canvas
> webpack-dev-server --inline --hot

ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wdm」: Hash: 99985e9b8632c783a375
Version: webpack 4.12.1
Time: 819ms
Built at: 2018-06-30 18:45:48
        Asset     Size  Chunks             Chunk Names
    bundle.js  354 KiB    main  [emitted]  main
bundle.js.map  406 KiB    main  [emitted]  main
Entrypoint main = bundle.js bundle.js.map
[./js/color.js] 359 bytes {main} [built]
[./js/index.js] 628 bytes {main} [built]
[./node_modules/loglevel/lib/loglevel.js] 7.68 KiB {main} [built]
[./node_modules/sockjs-client/dist/sockjs.js] 176 KiB {main} [built]
[./node_modules/url/url.js] 22.8 KiB {main} [built]
[./node_modules/webpack-dev-server/client/index.js?http://localhost:8080] (webpack)-dev-server/client?http://localhost:8080 7.75 KiB {main} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.58 KiB {main} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.05 KiB {main} [built]
[./node_modules/webpack-dev-server/node_modules/strip-ansi/index.js] (webpack)-dev-server/node_modules/strip-ansi/index.js 161 bytes {main} [built]
[0] multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./js/index.js 52 bytes {main} [built]
[./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./node_modules/webpack/hot/dev-server.js] (webpack)/hot/dev-server.js 1.6 KiB {main} [built]
[./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 77 bytes {main} [built]
[./node_modules/webpack/hot/log-apply-result.js] (webpack)/hot/log-apply-result.js 1.27 KiB {main} [built]
[./node_modules/webpack/hot/log.js] (webpack)/hot/log.js 1010 bytes {main} [built]
    + 14 hidden modules
ℹ 「wdm」: Compiled successfully.

but when I navigate to the localhost:8080/alphabet.html it throws an error in the console

Uncaught SyntaxError: Unexpected token export . alphabet.js:30

I also notice there is no bundle.js file under build folder as mentioned in webpack.config.js

here is my folder strucure

├── README.md
├── alphabet.css
├── alphabet.html
├── build
├── fruits
├── js
      ├── alphabet.js
      ├── color.js
      └── index.js
├── .babelrc
├── package.json
└── webpack.config.js
  • node -v 8.9.2
  • npm -v 5.5.1
  • macOS -v 10.13.3
  • babel --version
    6.26.0 (babel-core 6.26.3)

.babelrc

{
    "presets": ["@babel/preset-env"]
}

package.json

 "scripts": {
    "webpack": "webpack-dev-server --inline --hot",
    "start": "http-server"
  },
  "main": "./js.index.js",

  "devDependencies": {
    "@babel/core": "^7.0.0-beta.51",
    "babel-loader": "^8.0.0-beta.4",
    "babel-register": "^6.26.0",
    "jsxobj": "^1.1.0",
    "webpack": "^4.12.1",
    "webpack-cli": "^3.0.8",
    "webpack-dev-server": "^3.1.4",
    "webpack-node-externals": "^1.7.2"
  },
  "dependencies": {
    "@babel/preset-env": "^7.0.0-beta.51",
    "babel-eslint": "^7.2.3",
    "babel-preset-es2015": "^6.24.1",
    "path": "^0.12.7"
  }

webpack.config.js

module.exports = {
  context: __dirname,
  entry: "./js/index.js",
  mode: "development",
  output: {
    path: __dirname + "/build",
    filename: "bundle.js"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"]
          }
        }
      }
    ]
  },
  devtool: "source-map",
  resolve: {
    extensions: [".html", ".js", ".json", ".css"]
  }
};

/js/index.js

import { fetchImage } from "./alphabet.js";
import { color } from "./color.js";


const colorBox = color;
console.log("colorBox", colorBox);

const len = Object.keys(colorBox).length;

fetchImage(colorBox);

js/alphabet.js

export const fetchImage = letter => {
  const fruit = fruits[letter] || "tamarindo";
  const request = new Request(`./fruits/${fruit}.png`, myInit);
  fetch(request)
    .then(response => response.blob())
    .then(blob => {
      const objectURL = URL.createObjectURL(blob);
      const img = new Image(200);
      img.src = objectURL;
      let element = document.getElementById("figure");
      while (element.firstChild) {
        element.removeChild(element.firstChild);
      }
      element.appendChild(img);
    });
};

My main doubt on this alphabet.html file

alphabet.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Alphabet</title>
   <link rel="stylesheet" href="./alphabet.css">
</head>
<body>
    <div class="content" >
    <section class="alphabet"></section>
    <figure id="figure"></figure>
</div>
<script  src="./js/alphabet.js"></script>
</body>
</html>

If I change <script src="./js/index.js"> than it throw error

Uncaught SyntaxError: Unexpected token {

i.e. import and export keyword not being recognized

How to solve this problem?


Solution

  • If your goal is to enable using import and export statements, you should use the module type on your script tag:

    <script type="module" ... />
    

    This will be ignored by older browsers that don't support it, meaning you can make sure that older browsers don't even try to parse this. To make sure newer browsers don't parse old code, you can use nomodule:

    <script type="text/javascript" nomodule ... />
    

    See the documentation on MDN for more info on using the <script> tag like in this way: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script