ECMAScript Modules

ECMAScript Modules (ESM) are the official standard format for packaging JavaScript code for reuse. They allow developers to modularize their code using various import and export statements.

Templates for ECMAScript Modules

Extension.js offers two ECMAScript Module templates:

  • New ESM Template: For creating a new tab page extension using ECMAScript Modules.
  • Content ESM Template: For creating content script-based extensions using ECMAScript Modules.

New ECMAScript Module Template

The New ESM template is ideal for extensions that need a new tab page and are built using ECMAScript Modules. This template includes everything needed to get started quickly with ESM.

New ESM Template

Try it yourself

npm
pnpm
yarn
npx extension@latest create my-extension --template=new-esm

Content ECMAScript Module Template

The Content ESM template is designed for creating content scripts using ECMAScript Modules, allowing you to inject JavaScript directly into web pages.

Content ESM Template

Try it yourself

npm
pnpm
yarn
npx extension@latest create my-extension --template=content-esm

Usage With An Existing Extension

To enable ECMAScript Modules in an existing extension, add "type": "module" to your package.json file. This tells Node.js and Extension.js to treat all JavaScript files as modules.

{
  "name": "my-extension",
  "version": "1.0",
  "description": "My Extension Example",
  "type": "module", // Added to enable ESM support
  "devDependencies": {
    "extension": "latest"
  },
  "scripts": {
    "dev": "extension@latest dev",
    "start": "extension start",
    "build": "extension@latest build"
  }
}

Key Differences Between ECMAScript Modules and CommonJS

When working with ECMAScript Modules, there are some important differences compared to CommonJS modules.

1. Relative Imports Must Include File Extensions

When importing local files, you must include the file extension (e.g., .js, .mjs).

// my-file.mjs

React does not need a file extension since it's imported from package.json
import React from 'react'

myImport requires a file extension since it's a local module
- import myImport from './myImport'
+ import myImport from './myImport.js'

2. Named Exports Are Not Available From Non-ESM

If you are working with a non-ESM file, only the "default" export can be imported. Named exports are not supported.

// my-file.js (CommonJS)

// myImport is an ESM, and it can only be imported via default export.
- import {myExportedMethod} from './myImport.mjs'
+ import myDefaultExport from './myImport.mjs'

3. CommonJS Syntax Is Not Supported

CommonJS syntax such as require, module.exports, __filename, and __dirname is not available in ECMAScript Modules. Attempting to use these will result in an error.

Handling Environment Variables in ECMAScript Modules

Extension.js provides support for environment variables in ECMAScript modules. You can access environment variables using process.env in any module. Ensure that your environment variables are prefixed with EXTENSION_PUBLIC_ to be available in the client-side code.

// example.mjs

console.log(process.env.EXTENSION_PUBLIC_API_KEY);
// Output: The value of EXTENSION_PUBLIC_API_KEY

Next Steps