JavaScript - 如何使 ES6 导入在浏览器中工作?

Roy*_*hal 7 javascript ecmascript-6 es6-module-loader es6-modules

我正在开始一个新项目,我想要在其中使用 ES6 样式模块,但是,我无法让它在浏览器中运行。我正在使用 Chrome。

我将问题隔离在很少的代码行中。

这是我的 2 个 TypeScript 文件:

应用程序

import { Component } from './component';

var component: Component = new Component();
Run Code Online (Sandbox Code Playgroud)

组件.ts

export class Component {

}
Run Code Online (Sandbox Code Playgroud)

以下是它们编译为 JavaScript 的方式:

应用程序.js

import { Component } from './component';
var component = new Component();
Run Code Online (Sandbox Code Playgroud)

组件.js

export class Component {
}
Run Code Online (Sandbox Code Playgroud)

我的 index.html 只包含一个脚本标签。我尝试了一些变体,但没有一个奏效。

index.html #1

<script src="src/app.js" type="module"></script>
Run Code Online (Sandbox Code Playgroud)

未加载脚本。(网络选项卡中没有请求)

index.html #2

<script src="src/app.js" type=module></script>
Run Code Online (Sandbox Code Playgroud)

未加载脚本。(网络选项卡中没有请求)

index.html #3

<script src="src/app.js"></script>
Run Code Online (Sandbox Code Playgroud)

未捕获的语法错误:意外的标记 {

我正在使用 tsc 通过 Visual Studio Code 转译 TypeScript。

任务文件

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "typescript",
            "tsconfig": "tsconfig.json",
            "problemMatcher": [
                "$tsc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "presentation": {
                "reveal": "silent"
            }
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

配置文件

{
  "compilerOptions": {
    "target": "es6",
    "sourceMap": false,
    "removeComments": false,
    "noImplicitReturns": true,
    "noImplicitAny": true,
    "preserveConstEnums": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "outDir": "../src/"
  },
  "exclude": [
    "logs",
    "node_modules"
  ]
}
Run Code Online (Sandbox Code Playgroud)

ymz*_*ymz 8

老实说 - 我认为这是一个很好的问题,因为JS它广泛用于服务器端和客户端应用程序,这导致了开发人员之间已经存在的混淆

很明显,您的TS代码是作为服务器端代码编写的(可能在 上Node.js)。尝试在客户端运行它(按原样)是......好吧......棘手。原因:您在代码中使用的语法假设在服务器端(而不是客户端)上运行。有解决方法吗?嗯,是!

好消息:

JS ES6确实有一个本地模块加载器!(检查 MDN

坏的:

  • 语法与Node.js模块加载器语法不同(导出模块时)
  • 支持非常局部(仅限现代浏览器)

一些补充说明:

  • 模块加载的通用语法与名为 require js ( https://requirejs.org/ )的第三方库相关联。你可以在客户端项目中使用这个库,但你必须安装它并正确配置它(文档很清楚如何做到这一点)
  • 您始终可以使用像 grunt ( https://gruntjs.com/ ) 或类似项目这样的任务运行器来帮助您将所有代码缩小并统一到生产中的单个文件中。你为什么问?当客户端获取您的网站时,它显然会帮助您减轻负载(就网络流量而言,文件越少越好)

如您所见,您的问题没有快速或简单的答案......但它可能是提高您的知识和构建更好的现代网络应用程序的一个很好的起点。

更新

根据要求,我创建了一个小沙盒演示,展示了如何使用 ES6 原生模块 ( https://codesandbox.io/s/oj2rwm9v35 )

索引.html

<html>
<body>
    <div id="app"></div>
    <script type="module" src="src/primary.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

初级.js

import test from "./test";

test();
Run Code Online (Sandbox Code Playgroud)

测试.js

export default function test() {
  document.querySelector("#app").textContent = "Hello JS module!";
}
Run Code Online (Sandbox Code Playgroud)

  • 我正在尝试使用原生 ES6 模块。我在那里做什么和它应该如何之间有什么区别?以下导入: import { Component } from './component'; 似乎是正确的语法。也改为 import { Component } from './component.js'; 没什么区别。为什么 app.js 甚至没有加载?我无法从您的回答中真正理解,如果您能详细说明这一点,那就太好了。 (2认同)