preface

I have been engaged in front-end work for more than two years. I have learned from jQ at the beginning, angular later, React and VUE and applied them into practice. Since ES6, Node, scaffolding, writing code has been a flying experience. Until one day, with native development, there was a problem. I need to import another file on the native page, and I habitually import that file, but it doesn’t work…

Uncaught SyntaxError: Unexpected String Unexpected String I use js in Vue,React,Angular, etc. Why not write native? I knew about Babel, but DIDN’t realize that import needed to be translated by Babel. Leaving Babel is like not knowing how to write ES6. It can be seen that my cognition is limited by the convenient framework in the past, and I also understand import/export in ES6 for a long time, because they are interwoven and difficult to understand. Let me summarize a few common uses of import/export that I understand, as they are also the basis of ES6.

export

Export is to expose methods, classes, or data for use by another JS.

export const A = 1; // Expose the module variable A externally
export const Fn = (a)= >{}; // expose the module method Fn. Fn can use the module method.
// Export is equivalent to
const A= 1;
const Fn = (a)= >{};
export {A,Fn};
// The exported content can be aliased
export {A as B ,Fn as Fm};
// Export by default. There can only be one default export in a file
export default class extends react.Components{}
Copy the code
import

Import in native JS seems to be difficult to implement, or browser support for JS to use es6 syntax directly is not enough. However, it is necessary to use import in an environment with Babel, such as using a framework.

import './config.js'
// Import is used to import the entire config.js file and run all the code in the file except for export.
import vue from 'vue'
import aa from '.. /config.js'
// As the name implies, from a file. Where there is no relative path (such as Vue) is taken from the index.js folder in node_modules.
// import is the default exported module from the import file, which is equivalent to adding the corresponding module to the import file. Default imports can be aliased with AS
import {Fn,A} from 'a.js'; // import the exported method Fn and constant a from js file A
Copy the code
Es5 implementation of import/export

Es6 related syntax, in fact, is es5 related syntax sugar. I restored the scenario using import/export using Babel. The first part is the code of export.

// index.js
'use strict';
Object.defineProperty(exports, "__esModule", {
  value: true
});
var Fn = exports.Fn = function Fn() {}; exports.default = {a: 1
};
var A = exports.A = 1;
Copy the code

The first is that the code header declares strict mode, which is important. Exports: Exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports: exports But compared to CommonJs, Babel parses an extra export. Default, which is the default export. Also add attribute “exports.__esmodul =true” to export object, why? Let’s look again at the code that the import parses.

// import.js
'use strict';
var _index = require('./index');
var _index2 = _interopRequireDefault(_index);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
(0, _index.Fn)();
console.log(_index.A);
console.log(_index2.default);
Copy the code

As you can see here that the import file uses require(), you can be sure that Babel parses the module with reference to CommonJs. Then you can see the _interopRequireDefault function in the import file, which explains the use of “exports.__esmodul =true” to check whether the import module passed the Babel resolution. This way Babel can safely call the exported object “exports.default” from the loaded module. If the loaded module is not detected, it may be a third-party composite CommonJs module and the default export may not exist, in which case the default export points to the module itself. “(0, _index.fn)();” I’ve been working on the front end for two years and I haven’t seen it written this way. It’s kind of like executing functions immediately. If (“(0, _index.Fn)(); This comma expression is equivalent to _index.Fn(), but the context is bound to the global object, so it’s really equivalent to foo.bar.call(GLOBAL_OBJECT). Class imports and exports are similar to functions, and the parsed code is a bit long so I won’t give you an overview here.

conclusion

The significance of modularity to the front end is huge, and the emergence of ES6 has an unprecedented impact on the front end. Given the prevalence of three frameworks in today’s front-end world, is there a rationale for thinking about this approach as we write business code? Before ES6, JS modularization needs to use one or several of the complex CommonJS, SeaJS and RequireJS, which also needs to have higher requirements on the foundation. The framework is easy to develop, but the foundation is the true strength of a person. The situation may change in the future, but the solid foundation of knowledge is the sword to break through the future. I used to rely too much on the framework, think that the framework will be the front end, see mountains are mountains. So that out of the frame, began to look at the mountain. Only if the foundation is polished, can you see the mountain is small.

The original link: tech.gtxlab.com/import.html


About the author: Zhang Shuan, Renhe future big data front-end engineer, focusing on HTML/CSS/JS learning and development.