Uncaught SyntaxError: Cannot use import statement outside a module (at statement.js:1:1)
1、Uncaught SyntaxError: Cannot use import statement outside a module (at statement.js:1:1)。参考:重构:改善既有代码的设计 (第2版)。如图1
Uncaught SyntaxError: Cannot use import statement outside a module (at statement.js:1:1)
statement.html:37 Uncaught ReferenceError: statement is not defined
at statement.html:37:13
2、代码实现如下,如图2
statement.html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>重构,第一个示例</title>
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%20%20%20%20%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22statement.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%0A%20%20%20%20%20%20%20%20let%20invoice%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22customer%22%3A%20%22BigCo%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22performances%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22playID%22%3A%20%22hamlet%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22audience%22%3A%2055%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22playID%22%3A%20%22as-like%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22audience%22%3A%2035%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22playID%22%3A%20%22othello%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22audience%22%3A%2040%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%0A%20%20%20%20%20%20%20%20let%20plays%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22hamlet%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22name%22%3A%20%22Hamlet%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22tragedy%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22as-like%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22name%22%3A%20%22As%20You%20Like%20It%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22comedy%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22othello%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22name%22%3A%20%22Othello%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22tragedy%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%0A%20%20%20%20%20%20%20%20console.log(statement(invoice%2C%20plays))%3B%0A%20%20%20%20%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
</head>
<body>
</body>
</html>
statement.js
import createStatementData from './createStatementData.js';
function renderPlainText(data, plays) {
let result = `Statement for ${data.customer}\n`;
for (let perf of data.performances) {
result += ` ${perf.play.name}: ${usd(perf.amount)} (${perf.audience} seats)\n`;
}
result += `Amount owed is ${usd(data.totalAmount)}\n`;
result += `You earned ${data.totalVolumeCredits} credits\n`;
return result;
}
function usd(aNumber) {
return new Intl.NumberFormat("en-US",
{
style: "currency", currency: "USD",
minimumFractionDigits: 2
}).format(aNumber / 100);
}
function statement(invoice, plays) {
return renderPlainText(createStatementData(invoice, plays));
}
createStatementData.js
export default function createStatementData(invoice, plays) {
const result = {};
result.customer = invoice.customer;
result.performances = invoice.performances.map(enrichPerformance);
result.totalAmount = totalAmount(result);
result.totalVolumeCredits = totalVolumeCredits(result);
return result;
function enrichPerformance(aPerformance) {
const result = Object.assign({}, aPerformance);
result.play = playFor(result);
result.amount = amountFor(result);
result.volumeCredits = volumeCreditsFor(result);
return result;
}
function playFor(aPerformance) {
return plays[aPerformance.playID];
}
function amountFor(aPerformance) {
let result = 0;
switch (aPerformance.play.type) {
case "tragedy":
result = 40000;
if (aPerformance.audience > 30) {
result += 1000 * (aPerformance.audience - 30);
}
break;
case "comedy":
result = 30000;
if (aPerformance.audience > 20) {
result += 10000 + 500 * (aPerformance.audience - 20);
}
result += 300 * aPerformance.audience;
break;
default:
throw new Error(`unknown type: ${aPerformance.play.type}`);
}
return result;
}
function volumeCreditsFor(aPerformance) {
let result = 0;
result += Math.max(aPerformance.audience - 30, 0);
if ("comedy" === aPerformance.play.type) result += Math.floor(aPerformance.audience / 5);
return result;
}
function totalAmount(data) {
return data.performances
.reduce((total, p) => total + p.amount, 0);
}
function totalVolumeCredits(data) {
return data.performances
.reduce((total, p) => total + p.volumeCredits, 0);
}
}
3、参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Modules 。JavaScript 模块。需要把 type=”module” 放到 script 标签中,来声明这个脚本是一个模块。
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20type%3D%22module%22%20src%3D%22statement.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
4、刷新页面:file:///E:/wwwroot/refactoring/1/statement.html。报错:Access to script at ‘file:///E:/wwwroot/refactoring/1/statement.js’ from origin ‘null’ has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.。如图3
Uncaught ReferenceError: statement is not defined
at statement.html:43:17
(匿名) @ statement.html:43
statement.html:1 Access to script at 'file:///E:/wwwroot/refactoring/1/statement.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.
statement.html:8 GET file:///E:/wwwroot/refactoring/1/statement.js net::ERR_FAILED
5、需要注意本地测试 — 如果你通过本地加载 HTML 文件 (比如一个 file:// 路径的文件), 你将会遇到 CORS 错误,因为 JavaScript 模块安全性需要。你需要通过一个服务器来测试。
6、打开:http://localhost/refactoring/1/statement.html,仅剩下报错:Uncaught ReferenceError: statement is not defined。但是已经有正常的输出结果。如图4
Uncaught ReferenceError: statement is not defined
at statement.html:43:17
(匿名) @ statement.html:43
7、将 html 中的 js 代码剪切至 statement.js 中,实现如下。不再报错。如图5
statement.html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>重构,第一个示例</title>
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%20%20%20%20%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20type%3D%22module%22%20src%3D%22statement.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
</head>
<body>
</body>
</html>
statement.js
import createStatementData from './createStatementData.js';
function renderPlainText(data, plays) {
let result = `Statement for ${data.customer}\n`;
for (let perf of data.performances) {
result += ` ${perf.play.name}: ${usd(perf.amount)} (${perf.audience} seats)\n`;
}
result += `Amount owed is ${usd(data.totalAmount)}\n`;
result += `You earned ${data.totalVolumeCredits} credits\n`;
return result;
}
function usd(aNumber) {
return new Intl.NumberFormat("en-US",
{
style: "currency", currency: "USD",
minimumFractionDigits: 2
}).format(aNumber / 100);
}
function statement(invoice, plays) {
return renderPlainText(createStatementData(invoice, plays));
}
let invoice = {
"customer": "BigCo",
"performances": [
{
"playID": "hamlet",
"audience": 55
},
{
"playID": "as-like",
"audience": 35
},
{
"playID": "othello",
"audience": 40
}
]
};
let plays = {
"hamlet": {
"name": "Hamlet",
"type": "tragedy"
},
"as-like": {
"name": "As You Like It",
"type": "comedy"
},
"othello": {
"name": "Othello",
"type": "tragedy"
}
};
console.log(statement(invoice, plays));





近期评论