使用ES6模块化出现“Uncaught SyntaxError: Unexpected token {”这种错误的解决方案

起因

之前使用ES6模块化场景要么就是在vue-cli,要么就是webpack或者babel中编译好使用的,如今很多浏览器已经支持这个语法了,比如:

  • Safari 10.1.
  • Chrome 61.
  • Firefox 60.
  • Edge 16.

心血来潮的我立马弄了个demo。我在main.js中引入了一个hello模块,下面是目录结构和代码:
在这里插入图片描述
hello.js

const sayHi = name => {
	alert(`hello,${name}`)
};

export { sayHi };

main.js

import { sayHi } from 'hello.js';

const name = 'laocao';
sayHi(name);

index.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title></title>
	<link rel="stylesheet" href="">
</head>
<body>
	<script type="text/javascript" src="main.js"></script>
</body>
</html>

Chrome执行index.html后:
在这里插入图片描述
我心想,这是啥问题?从来没见过啊,于是乎上各大论坛开始找这个,但大部分不是我想要的答案,但有幸阅读了
一篇老哥的文章后,终于解决了,下面是解决方案。

解决方案

1.首先声明script标签的类型为module

<script type="module" src="main.js"></script>

这样浏览器就会把这个标签里面的内容作为ECMAScript的模块

2.当前import引入模块的路径需要通过./这种类似的标识符引入,比如当前路径就必须用./

//支持
import { sayHi } from './hello.js';
//不支持
import { sayHi } from 'hello.js';

到了这个时候,我们以为没有啥问题了吧,但是!请看浏览器:
在这里插入图片描述
似曾相识啊,好像跨域被拒绝了?不就是引入一个模块吗,为什么还涉及到跨域呢?我们先打开运行在web服务器上测试一下,看有没有问题,然后再解释:
使用ES6模块化出现“Uncaught SyntaxError: Unexpected token {”这种错误的解决方案_第1张图片
问题解决了!大功告成!

3.资源需要部署在同一个web服务器上,获取请求的模块有跨域权限。我们看看那位老哥说的话:

Unlike regular scripts, module scripts (and their imports) are fetched with CORS. This means cross-origin module scripts must return valid CORS headers such as Access-Control-Allow-Origin: *.

我大概翻译一下意思是:不像常规的scripts标签,被指定为module类型的标签总是和跨域联系在一起。意思是说有跨域的模块化标签必须返回一个像Access-Control-Allow-Origin的响应头。有点类似于JSONP,那么我们需要把资源都部署在同一个Web服务下或者在服务器端,就不会有这种问题了。或者在服务器的头设置上面那个允许跨域的字段就行了。

参考

https://jakearchibald.com/2017/es-modules-in-browsers/

你可能感兴趣的:(ECMAScript,6+)