前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Going Bundleless: ES Modules

Going Bundleless: ES Modules

作者头像
^_^肥仔John
发布2021-09-06 15:21:50
4730
发布2021-09-06 15:21:50
举报
文章被收录于专栏:偏前端工程师的驿站

It's really a long period I have been out of touch to front-end trending, until I try to add petite-vue into our team's codebase recently. Fortunately, while our age-old project is built by JSP and LayUI which is an old fashion back-end friendly UI library, there is no need to support IE any more. During exploring the petite-vue codebase, I discovered the brand new build tooling Vite, which is a leaner and faster building solution for large front-end project base on ES module.

Up until 2015, there was no standard mechanism for code reuse. And about 7 years ago there were loads of attempts like IIFE, AMD, CommonJS and UMD trying to standardize this aspect. I had introduce seajs which implements spec of CommonJS in browser by Alibaba into my project at that moment. But there was no clear winner. Nowadays, ES module have been supported by modern browser and NodeJS natively. Wow, how time flies.

I'm sure you already know everything about ES module, so here's a quick recap about ES module in browser for myself 😄

Exporting Modules

In the contrast to classic scripts, the variables and other programming objects are declared inside the file are scoped to the module itself. And explicitly expose API surface by export or export default statements.

There three categories of exports.

  1. Named exports
代码语言:javascript
复制
export let name1, name2, ..., nameN
export let name1 = 1,  name2 = 2, ..., nameN
export function funct1 {}
export class User {}

export {name1, name2} 
export {name1 as n1, name2} // renaming exports
export {name1: n1, name2} =  o // exporting destructure assignment with renaming
  1. Default exports
代码语言:javascript
复制
export default expression // exporting the result of expression as defualt export
export default function(){}
export {name1 as default, name2}
  1. Aggregating exports (using in entry module commonly)
代码语言:javascript
复制
export * from './loadash.js' // exporting all named exports
export * as Loadash from './loadash.js' // exporting Loadash as default export to the next module
export {name1 as n1, name2} from './my.js'
export {default} from './ramda.js' // exporting the default export

The Caveats

  1. The export statement is used to create live binding to programming objects of current module. As the live binding stated, the value of the imported binding is subject to change in the module that exposed. When a module updates the value of a binding it exposed, the update will be visible instant in its imported value.
  2. Strict mode is the only mode for exported modules.

Loading Modules

Module Scripts

We can load JavaScript modules using scripts with type="module" to reference the module file by src, or author the module directly inline.

代码语言:javascript
复制
<script type="module" src="/path/to/app-es.js"></script>
<script type="module">
import './module1-es.js'

console.log('Have nice day little lady!')
</script>

Static Imports

We can import modules by import statement statically as below.

代码语言:javascript
复制
import Ramda from './ramda.js' // import default export
import * as loadash from './loadash.js' // import all named exports as an object
import {debounce as deb, filter} from './loadash.js' // import some of named exports, and rename with more convenient alias
import _, {debounce as deb, filter} from './loadash.js' // condense the importations for default export and named exports to one statement
import './mycode.js' // import the module for side effect only, without any importings.
  1. Static imports load modules in eager strategy. That said, JavaScript runtime will load the ES module first before running any other code within the module.
  2. import statements are allowed to place in to most top lines except comments only.

Dynamic Imports

The usage of dynamic imports is similar to static imports very much, except we can call the import function and then get the importing module from the return value of which type is Promise in any where within module.

代码语言:javascript
复制
async function(){
    const {default: Ramda} = await import('./ramda.js') // import default export
    const loadash = await import('./loadash.js') // import all named exports as an object
    const {debounce: deb, filter} = await import('./loadash.js') // import some of named exports and rename them
    import('./mycode.js') // import the module side effect only, without any importings.
}

The Rules to Import Paths

In browser the import paths should be the full path to the importing module in either absolute or relative to your module. And it should include the file extension as well.

代码语言:javascript
复制
import '/absolute/path/to/importing/module-with-file-extension.js'
import './relative/path/to/importing/module-with-file-extension.js'

However, there is a specific way to resolve modules in NodeJS, so we can use the bare module imports without file extension as CommonJS do.

代码语言:javascript
复制
import 'foo'
import './test'

How about Images and Stylesheet?

If you have build project with Webpack or other modern build toolings, you probobly ask can we import images, stylesheet or other static resources by import statement or function. As a result to that is no, I'm so apologize to that, but still no actually. Because ES module landed for JavaScript only, there is no support for non-JavaScript resources directly. So how we can do?

There is import.meta.url storing the absolute path of current module, we can leverage it as the base url to resolve the full path of image and others. Not smart but works at very least.

代码语言:javascript
复制
const imgSrc = new URL('./avatar.jpg', import.meta.url)

The Final Words

ES module came as the standard module mechanism, which has been called for decades more or less. Although it's not perfect as we expect, it might be a great beginning for the next generation of front-end I guess.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Exporting Modules
    • The Caveats
    • Loading Modules
      • Module Scripts
        • Static Imports
          • Dynamic Imports
            • The Rules to Import Paths
            • How about Images and Stylesheet?
            • The Final Words
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档