difference between require and import ?

Cause I run into a weird situation.

var angular = require('angular');
angular.module('app', [
  'ngSanitize',
  'ngCookies',
  'ui.router'
]);

require('angular-sanitize');
require('angular-cookies');
require('angular-ui-router');

require('../services');
require('../directives');
require('../filters');

Everything works fine. But I am confused with this, I thought all those require will run first, turns out , I am wrong. And the run order is also diff between npm packages (like angular-sanitize, angular-cookies) and those files (like ../services, ../directives, ../filters).

Because the app module depends on ngSanitize, ngCookies and ui.router. So those module must be available before declaring app module, right ?
And those services , directives and filters depend on app module, So those stuff should run after the app module is available.

So here is my first question, _What’s the run order?_

Then I want to use import instead of require.

import angular from 'angular';
angular.module('app', [
  'ngSanitize',
  'ngCookies',
  'ui.router'
]);

import 'angular-sanitize';
import 'angular-cookies';
import 'angular-ui-router';

import '../services';
import '../directives';
import '../filters';

And now everything works as my expecting. Those import stuff will run first, and then run the angular module declare code. Cause those services, directives and filters depend on the app module, so it throws the the app module is not available ,... error.

Here is my second question, _What’s the difference between require and import?_

I am using webpack 1.12.12 and babel-loader 6.2.1.

Author: Fantashit

4 thoughts on “difference between require and import ?

  1. I think a big part of your confusion is coming from Angular itself. The dependencies defined in
    angular.module('app', [ 'ngSanitize', 'ngCookies', 'ui.router' ]); don’t actually get loaded by Angular until the application is bootstrapped, meaning that importing them after calling angular.module is totally legal (if a bit of a headache). So in answer to your first question, the run order of your requires is exactly as it appears in your source code.

    My understanding of the new module spec is pretty limited, but the main difference between require and import is that import is always run at the very beginning of the file (if you look at Babel’s output, they get hoisted to the top), and can’t be run conditionally. This means that you can guarantee all the imports have completed before any of your code runs. Whereas require can be used inline, conditionally, etc.

  2. Hey @lili21. What @17cupsofcoffee answered is actually the correct answer.

    imports get sorted to the top of the file, and requires stay where they were put. So the run-order only changes with import.

    If you have any further questions, feel free to re-open!

  3. It does convert import into a CommonJS require (well, babel-loader does – Webpack 1 doesn’t understand ES2015 module syntax without it, although that’s being added natively in Webpack 2).

    Say you had a file that contained the following code:

    var module1 = require("module1");
    import module2 from "module2";
    
    console.log(module1);
    console.log(module2);

    The JavaScript that gets output would be:

    "use strict";
    
    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
    
    var _module2 = require("module2");
    
    var _module22 = _interopRequireDefault(_module2);
    
    var module1 = require("module1");
    
    console.log(module1);
    console.log(_module22["default"]);

    The two things to note here are:

    • module2‘s require statement gets hoisted to before the rest of your code, emulating the way that ES2015 imports are run before the rest of the code.
    • Babel adds an extra function called _interopRequireDefault, which it then uses to wrap your ES2015 imports (hence the references to _module22 in the generated code). Without over complicating things, this effectively checks to see if the module you imported was a CommonJS module, and if so, sets module.exports as the default (and only) export – hence why you can use them both together without any changes in syntax.

    Again, none of this is actually Webpack’s doing, it’s all Babel – but this is how Babel gets your code into a format that Webpack can understand. I don’t know if I explained this very well, so if you have any more questions, let me know!

Comments are closed.