Skip to content
A custom transformer that can be used with ttypescript to transform ts imports to browser style imports
TypeScript JavaScript
Branch: develop
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
docs
specs
src
.gitignore
.prettierrc
CHANGELOG.md
LICENSE
README.md
api-extractor.json
build-doc.js
package-lock.json
package.json

README.md

Emit a ES Module Web project by only ttypescript

npm version

Jump to Install, Use cases, Motivation

Intro

This typescript transformer helps you to emit a browser compatible ESModule output. In general, it do two things:

  1. Add a ".js" after the local import
  2. Transform the node style dependencies (e.g. import React from "react") to
    1. A global variable access (const React = globalThis.React)
    2. A CDN (import _ from "https://cdn.pika.dev/lodash-es@4.17.15")
    3. Another CDN (import _ from "https://unpkg.com/lodash-es@4.17.15?module")
    4. Snowpack style import (import _ from "/web_modules/lodash-es.js")
    5. [🧪Experimental] Read import rule from Import Map

Input

import './polyfill'
import * as React from 'react'

Output

import { __UMDBindCheck as __UMDBindCheck } from "https://cdn.jsdelivr.net/npm/@magic-works/ttypescript-browser-like-import-transformer@1.4.1/es/ttsclib.min.js";
const React = __UMDBindCheck(globalThis.React, [], "react", "globalThis.React", false);
import "./polyfill.js";

Install

  1. Install typescript and ttypescript, and this transformer into your project if you don't already have them.

    npm install --save-dev typescript
    npm install --save-dev ttypescript
    npm install --save-dev @magic-works/ttypescript-browser-like-import-transformer
    
  2. You should use ESModule like target (es2015, esnext, etc) in your compiler options

    // tsconfig.json
    {
        "compilerOptions": {
            "module": "es2015",
            "plugins": [
                {
                    "transform": "@magic-works/ttypescript-browser-like-import-transformer",
                    "after": true
                    // Configs go here.
                }
            ]
        }
    }
  3. Write some typescript with normal imports

    import React from 'react'
  4. Compile using ttsc

    ttsc --project tsconfig.json
    

Use cases

Use with classic UMD dependencies

The default config of this transformer is "UMD" mode. All bare imports will be translated to a "UMD import". (e.g. import React from "react" becomes const React = globalThis.React). Then add a regular script tag to load React UMD.

Use with Webpack

Here is a template repo to help you use this transformer with Webpack. In this repo, all node style import is imported in a single file and packed by Webpack. Rest of the source code never get handled by Webpack but emitted by ttypescript (a enhanced typescript cli that allows you to specify transformer programmatically).

Use with Snowpack

See the TTypeScript Support in the Importing Packages by Name section.

/* tsconfig.json */
{
    "compilerOptions": {
        "module": "es2015",
        "plugins": [
            {
                "transform": "@magic-works/ttypescript-browser-like-import-transformer",
                "after": true,
                "bareModuleRewrite": "snowpack"
            }
        ]
    }
}

Use with CDN

Pika CDN and unpkg are two CDNs that friendly to ES Module dependencies. This transformer also supports CDN import. (e.g. Before import _ from 'lodash-es' After import _ from 'https://cdn.pika.dev/lodash-es')

/* tsconfig.json */
{
    "compilerOptions": {
        "module": "es2015",
        "plugins": [
            {
                "transform": "@magic-works/ttypescript-browser-like-import-transformer",
                "after": true,
                "bareModuleRewrite": "pikacdn" // or "unpkg"
            }
        ]
    }
}

Motivation

Nowadays most of codes in our codebase are ESModules. You can emit browser executable JS files by tsc directly but you have to add the annoying .js extension to the end. (Related: PR: New --emitExtension and --noImplicitExtensionName compiler options)

On the other hand, it is hard to run ES Module codes with Node style dependencies, there're some solutions to this including Snowpack but Snowpack also have it's limits.

Options

See Options

Use programmatically

If you are using Node.js, import @magic-works/ttypescript-browser-like-import-transformer/cjs/node.js, it will export a ts.TransformerFactory<SourceFile>.

If you are in other environment or you want to modify the behavior of the transformer, use ./es/core.js and provide related I/O operations to create a ts.TransformerFactory<SourceFile>.

Once you get the ts.TransformerFactory<SourceFile>, you can use it like

const result = ts.transpileModule(source, {
    compilerOptions,
    transformers: {
        after: [
            transformer.default(
                // TODO: remove this dependency. Only `program.getCurrentDirectory()` is used currently
                program,
                {
                    after: true,
                    // config here
                },
            ),
        ],
    },
})
You can’t perform that action at this time.