【问题标题】:JavaScript - How to make ES6 imports work in browser?JavaScript - 如何使 ES6 导入在浏览器中工作?
【发布时间】:2019-04-01 01:45:31
【问题描述】:

我正在开始一个新项目,我希望在其中拥有 ES6 风格的模块,但是我无法让它在浏览器中运行。我正在使用 Chrome。

我将问题分解为几行代码。

这是我的 2 个 TypeScript 文件:

app.ts

import { Component } from './component';

var component: Component = new Component();

component.ts

export class Component {

}

下面是它们如何编译成 JavaScript:

app.js

import { Component } from './component';
var component = new Component();

component.js

export class Component {
}

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

index.html #1

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

脚本未加载。 (网络标签中没有请求)

index.html #2

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

脚本未加载。 (网络标签中没有请求)

index.html #3

<script src="src/app.js"></script>

Uncaught SyntaxError: Unexpected token {

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

tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "typescript",
            "tsconfig": "tsconfig.json",
            "problemMatcher": [
                "$tsc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "presentation": {
                "reveal": "silent"
            }
        }
    ]
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es6",
    "sourceMap": false,
    "removeComments": false,
    "noImplicitReturns": true,
    "noImplicitAny": true,
    "preserveConstEnums": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "outDir": "../src/"
  },
  "exclude": [
    "logs",
    "node_modules"
  ]
}

【问题讨论】:

  • 很简单:他们没有
  • 你确定吗?如果是这样,我在这里误解了什么? contentful.com/blog/2017/04/04/…
  • 是的,您可以直接在最新的浏览器中使用模块,无需打包器!您应该在不定义任何特定模块系统的情况下将 ts 转换为 js 文件。然后你可以在浏览器中加载模块&lt;script type=‘module’ src=‘thing.js’&gt;
  • 好的,我现在正在做,js 看起来更干净了,但是脚本仍然没有加载。我在原始问题的底部添加了更多信息。
  • 你试过写一个最小的构造函数吗? TS classes

标签: javascript ecmascript-6 es6-modules es6-module-loader


【解决方案1】:

说实话 - 我认为这是一个很好的问题,因为JS 在服务器端和客户端应用程序中都被广泛使用,这导致了开发人员之间已经存在的困惑

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

好消息:

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

坏的:

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

一些补充说明:

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

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

更新

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

index.html

<html>
<body>
    <div id="app"></div>
    <script type="module" src="src/primary.js"></script>
</body>
</html>

primary.js

import test from "./test";

test();

test.js

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

【讨论】:

  • 感谢您的回答。它仍然与更新的问题描述相关吗?
  • 我相信是......你的选择是:使用原生 ES6 模块(并改变你导出函数的方式),安装 require(并正确配置它)或者只是决定使用一个任务runner 帮助您将 TS 转换为适合客户端环境的单个缩小 JS 文件
  • 我正在尝试使用原生 ES6 模块。我在那里做的事情和应该做的事情有什么区别?以下导入: import { Component } from './component';似乎是正确的语法。也改为 import { Component } from './component.js';没有什么区别。为什么 app.js 甚至没有加载?从您的回答中我无法真正理解,如果您能详细说明这一点,那就太好了。
  • 感谢您的详细说明,所以我认为问题不在于代码本身。当您在本地文件系统中打开它时,这对您有用吗?对我来说不是。您的代码和我的代码都只有在服务器上运行时才能工作。知道为什么吗?
  • 你是对的。它在从 localhost 而不是从本地文件系统运行时工作。另请注意,我定义了一个主模块(其行为类似于应用程序模块)并尝试从那里加载更多模块 - 这种方法(将您的应用程序定义为模块,从脚本标签加载它并从此应用程序模块加载其他模块)应该做这个把戏..至少在我看来
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-13
  • 2021-11-03
  • 2021-11-03
  • 2018-08-01
  • 2015-05-16
  • 2010-12-12
相关资源
最近更新 更多