The problem background
An Angular4 project failed to connect to the SDK because the console reported undefined
Introduce methods
import sa from 'sa-sdk-javascript';
sa.init({
server_url: 'https://xxx.com';
});
Copy the code
Final solution
import * as sa from 'sa-sdk-javascript';
sa.init({
server_url: 'https://xxx.com';
});
Copy the code
What’s the difference between these two introductions? Let’s do an example
exporter.js
export default {
one: "One".two: "Two".three: "Three"};export var a = 'a';
Copy the code
importer.js
// Has 3 props ['one', 'two', 'three']
import anyname from './exporter';
// Has 2 props ['default', 'a'].
import * as allExports from './exporter';
import {one} from './exporter';
import two from './exporter';
console.log(anyname);
console.log(allExports);
console.log(one);
console.log(two);
Copy the code
The output is as follows
{one: "One".two: "Two".three: "Three"}
one: "One"
three: "Three"
two: "Two"
__proto__: Object
a: (...).default: {one: "One".two: "Two".three: "Three"}
Symbol(Symbol.toStringTag): "Module"
__esModule: trueGet a: ƒ ()__proto__: Object
undefined
{one: "One".two: "Two".three: "Three"}
one: "One"
three: "Three"
two: "Two"
__proto__: Object
Copy the code
This is an example of success and an example of failure before that
importer.js
// Has 3 props ['one', 'two', 'three']
import defaultExport from './exporter';
// Has 2 props ['default', 'a'].
import * as allExports from 'exporter';
console.log(defaultExport)
console.log(allExports)
Copy the code
Run node importer. Js directly
import defaultExport from './exporter'; ^^^^^^^^^^^^^ SyntaxError: Unexpected identifier at new Script (vm.js:74:7) at createScript (vm.js:246:10) at Object.runInThisContext (vm.js:298:10) at Module._compile (internal/modules/cjs/loader.js:646:28) at Object.Module._extensions.. js (internal/modules/cjs/loader.js:689:10) at Module.load (internal/modules/cjs/loader.js:589:32) at tryModuleLoad (internal/modules/cjs/loader.js:528:12) at Function.Module._load (internal/modules/cjs/loader.js:520:3) at Function.Module.runMain (internal/modules/cjs/loader.js:719:10) at startup (internal/bootstrap/node.js:228:19)Copy the code
What makes it work? It runs in an Angular project, and the key is Babel
As for the understanding of import and export, it is not deep. Learn the syntax of Module in ES6
Here are the key words notes
I. Historyjs
There is no module system
Js’s original design had no concept of modules at all
Defect: Inability to break large programs into small interdependent files (modules) and put them together in a simple way
In fact this is for engineering defects, the reason for the large program into dependent small module, is for the sake of different functions can be separated for development and maintenance, like small system, and finally rebuilt in a simple way is because the program run does not focus on how a more complex, as long as the program runs through can run, Divide-and-conquer is simply a way for humans to help themselves understand and process vast programs.
There is no harm without comparison: ruby, a scripting language, has its own require, Python has its own import, and even CSS has its own @import. Js before ES6 is humiliated by comparison
Second,CommonJS
andAMD
It was before es6community
The solution
CommonJS for servers, AMD for browsers
Third, es6 fromLanguage standard
Module functions are realized on the level, and the implementation is quite simple
Nice, raised his head from then on
Es6’s module capabilities can replace CommonJS and AMD as a universal module solution
Fourth, es6 module design idea is as far as possiblestatic
(Another new concept)
Statically means that module dependencies and input and output variables can be determined at compile time
Five, the contrastCommonJS
Advantages such asCommonJS
The module is an object, and you must look for object properties when entering
It is very stiff
I feel it is necessary to take a look at the history of CommonJS and AMD
- CommonJS specification
- CommonJS specification for Webpack Chinese documentation
Six, about staticCommonJS
Comparison with es6 modules
CommonJS
/ / CommonJS module
let { stat, exists, readFile } = require('fs');
/ / is equivalent to
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;
Copy the code
While the first line looks similar to the es6 module we’re using today, there are actually two key differences
- The above operation is actual
The overall load
thefs
Module, and just use the three methods in it - The above action is in the program
Run time loading
Because this object is only available at runtime (and therefore cannot be done at compile time)The static optimization
)
Es6 module
/ / ES6 module
import { stat, exists, readFile } from 'fs';
Copy the code
- Es6 modules are not objects, but pass
export
The commandexplicit
Specify the output code, then passimport
The command input - The above operation only loads these three methods. Other methods are not loaded
Load at compile time (statically loaded)
This is the advantage achieved from the language standard level (a shame), simply add two built-in keywords, through the command to complete the pre-compile module transmission declaration, the community solution can only curve save the country.
Seven, aboutexport
The command
- A module is an independent file
- All variables inside the file are not available outside the file
- External read module variables must be used
export
Output the variable
For example,
// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
Copy the code
Another way to write it
// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export { firstName, lastName, year };
Copy the code
Output method or class
export function multiply(x, y) {
return x * y;
};
Copy the code
export class multiply(x.y) {
return x * y;
};
Copy the code
Rename the output
function v1() {... }function v2() {... }export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVersion // The same output object (variable, class, method) can be renamed multiple times
};
Copy the code
Matters needing attention
export
The command specifies the external interface, which must establish a one-to-one relationship with variables in the module (interface name and variables in the module one-to-one).- You cannot output the value of a variable directly, but should output it as an interface
counter-examples
// Output the value directly
export 1;
var m = 1;
// Print the value of the variable directly
export m;
Copy the code
Positive solution
// Print the declared variable directly
export var m = 1;
// Declare variables first, then output variables
var m = 1;
export {m};
// Declare the variable first, then print the variable as an alias
var n = 1;
export {n as m};
Copy the code
The above three types of scripts are exported through interface M, through which other scripts obtain their internal values
The characteristics of
The interface output by the export statement is dynamically bound to its corresponding value, through which the real-time value inside the module can be obtained
For example,
export var foo = 'bar';
setTimeout(() = > foo = 'baz'.500);
Copy the code
The value of foo starts with bar and becomes baz after 0.5 seconds
This feature contrasts with CommonJS, where modules output a cache of values
Matters needing attention
export
It can appear anywhere in the module, but at the top of the module- If in the
Block-level scope
An error is reported because being in a conditional block prevents static optimization and defeats the purpose of the ES6 module
Eight, aboutimport
The command
import
The command accepts a pair of curly braces specifying what to import from another moduleThe variable name
– see case 1- The variable name in braces must match that of the imported module interface
The same name
- If you want to rename an imported variable, you can use it at import time
as
Rename it — see example 2 import
The command input variables areread-only
The properties of a variable can be overwritten, but this can be dangerous, affecting other places where the module is introduced — see Example 3 (Objects that are similar to const declarations can change their internal properties, modules)export
The output interface is equivalent to an object.
Case 1
// main.js
import { firstName, lastName, year } from './profile.js';
function setName(element) {
element.textContent = firstName + ' ' + lastName;
}
Copy the code
Case 2
import { lastName as surname } from './profile.js';
Copy the code
Example 3
import {a} from './xxx.js'
a.foo = 'hello'; // It is valid
Copy the code
Introducing way
- It can be a relative path or an absolute path
.js
Suffixes can be omitted- Import module name without path
The configuration file
Tells the JS engine the location of the module
Matters needing attention
import
Has a promotion effect that will be promoted to the head of the entire module first executed (essentially becauseimport
The command is executed at compile time, before the code runs) — see Example 1- Due to the
import
Statically executed, so cannot be usedexpression
andvariable
Because these are all inThe runtime
To get a syntactic interface to the result — see Example 2
Case 1
foo();
// Although the location is below, the execution precedes the foo() call
import { foo } from 'my_module';
Copy the code
Case 2
/ / an error
import { 'f' + 'oo' } from 'my_module';
/ / an error
let module = 'my_module';
import { foo } from module;
/ / an error
if (x === 1) {
import { foo } from 'module1';
} else {
import { foo } from 'module2';
}
Copy the code
Matters needing attention
import
The statement executes the loaded module- Repeat the same sentence many times
import
The statement is executed only once (singleton mode) — see Example 1 - Currently, through
babel
Transcoding,CommonJS
The modulerequire
Commands andes6
The moduleimport
Commands can coexist, but are not recommended becauseimport
inStatic analysis
Phase execution, the earliest execution in a module, may makerequire
Statement does not execute as expected — see example 2
Case 1
import 'lodash';
import 'lodash';
// Only loads once
import { foo } from 'my_module';
import { bar } from 'my_module';
/ / is equivalent to
import { foo, bar } from 'my_module';
// Only loads once
Copy the code
Case 2
require('core-js/modules/es6.symbol');
require('core-js/modules/es6.promise');
// Execute first
import React from 'React';
Copy the code
Ix. Loading the module as a whole
way
Use an asterisk (*) to specify an object on which all module output values are loaded
// circle.js
export function area(radius) {
return Math.PI * radius * radius;
}
export function circumference(radius) {
return 2 * Math.PI * radius;
}
Copy the code
One by one to load
// main.js
import { area, circumference } from './circle';
console.log('Circle area:' + area(4));
console.log('Circumference:' + circumference(14));
Copy the code
The overall load
import * as circle from './circle';
console.log('Circle area:' + circle.area(4));
console.log('Circumference:' + circle.circumference(14));
Copy the code
Pay attention to the point
The object in which the module is loaded as a whole can be analyzed statically and cannot be changed at run time
import * as circle from './circle';
// The following two lines are disallowed
circle.foo = 'hello';
circle.area = function () {};
Copy the code