ES6 Imports are confusing but great
Just noticed this on the BugSnag setup tutorial

From my understanding that’s not how imports work. The cool thing about imports is, even though they are more restrictive, they all happen before any code is executed which is really powerful. It means we can statically analyses code and make some really good optimisations.
Before import we had require which was good for its time but posed a problem. Let’s say we had the following code.
// foo.js
module.exports = {
foo: 'bar',
someOtherVar: 'that is never needed',
}// entry.js
var myConditionalModule = 'more foo'
if (Math.random() < 0.5){
myConditionalModule = require('foo.js')
}
console.log(myConditionalModule.foo)
If we run entry.js, because we are requiring a module at runtime we don’t know before execution if we’re going to need to require that foo.js module or not.
So if we were to minify the code we can’t really flatten out the script easily, it would look something like this.
// Our foo.js module
function module_foo(module){
module.exports = {
foo: 'bar',
someOtherVar: 'that is never needed',
}
}// Some 'require' boilerplate, its probably not correct, but it
// makes the point
function require(moduleFunc){
var module = { exports: {} }
moduleFunc(module)
return module.exports
}var myConditionalModule = 'more foo'
if (Math.random() < 0.5){
myConditionalModule = require(module_foo)
console.log(myConditionalModule.foo)
}
You can see its quite hard to understand what’s going on and that we had to add some require() boilerplate to make it work.
Now if we instead enforced no runtime module require’s, our code becomes a lot easier to analyse. We could rewrite the first block of code like this.
// foo.js
module.exports = {
foo: 'bar',
someOtherVar: 'that is never needed',
}// entry.js
// Do all the module importing before any code
var myConditionalModule = require('foo.js')
if (Math.random() < 0.5){
console.log(myConditionalModule.foo)
}
Notice the require() here is being used in the same way imports work, i.e. before any code is ran.
Now if we were to flatten the code
// Do all the module importing before any code
var myConditionalModule = {
foo: 'bar',
someOtherVar: 'that is never needed',
}
if (Math.random() < 0.5){
console.log(myConditionalModule.foo)
}Suddenly it becomes a lot easier for the compiler to understand and it could then optimise it by stripping out the someOtherVar because now it can tell that that variable is never used.
Furthermore when you write stuff like
import bugsnag from 'bugsnag-js'
const bugsnagClient = bugsnag('f1c7dcdc29e23c8f2832925f3b908b54') import ReactDOM from 'react-dom'
import React from 'react'
import createPlugin from 'bugsnag-react'
I think what actually happens is this
import bugsnag from 'bugsnag-js'
import ReactDOM from 'react-dom'
import React from 'react'
import createPlugin from 'bugsnag-react'const bugsnagClient = bugsnag('f1c7dcdc29e23c8f2832925f3b908b54')
That’s my understanding, now patiently waiting for someone to tell me it's all wrong.
