SkillAgentSearch skills...

Tscc

A collection of tools to seamlessly bundle, minify Typescript with Closure Compiler

Install / Use

/learn @theseanl/Tscc
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

TSCC

tscc npm version rollup-plugin-tscc npm version CircleCI

TSCC is a collection of tools to seamlessly bundle and minify Typescript project using Closure Compiler.

Migrate

It is easy to migrate an existing Typescript project to TSCC. To get a sense of what it is like, check out todomvc apps forked from the original tastejs/todomvc and modified to use TSCC.


Features

  • Automatically configures settings for tsickle and closure compiler, and wires up tsickle js outputs and sourcemaps to closure compiler, sorted in accordence with dependency information, as required by closure compiler.
  • Provides an alternative rollup build using rollup-plugin-tscc plugin, emulating the chunking behaviour of closure compiler to get the same set of output files as what closure compiler would produce.
  • External module support: looks up required nodejs modules and wires them so that externs are generated, and transforms any code that uses externally imported variables. Think of it as an analogue of "external" option of webpack or "globals" option of rollup for closure compiler.

Background

Closure is a wonderful system of tools. The closure compiler is the best javascript minifier and bundler, but it is known to be very difficult to use. Documentations are scarce, and integration with external tools is not well-established.

Tsickle is another wonderful tool. It has finally made it ergonomic to write codes that can naturally be consumed by closure compiler — it transforms .ts files to well-annotated .js files, which would otherwise not even be consumed by the compiler and automatically generates externs file from declaration files. However, as in closure compiler, one has to be careful with setting it up, otherwise strange bugs can occur which are not actively worked on as of now. Also, it only performs transpilation — there is no tool to feed transpiled files to closure compiler, which is another painful part.

TSCC aims to encapsulate these tools in a minimal, ergonomic API, and provides a faster and easier alternative bundling method using Rollup via a companion rollup-plugin-tscc plugin, which is great for rapid development. TSCC can be used as a drop-in replacement for rollup in existing projects using rollup, after moving chunk information in rollup.config.js to tscc.spec.json. TSCC spec file is a single source of truth for all of your module bundling information.

Getting started

Suppose that we have a project with the following directory structure.

my_project
├───tsconfig.json
├───rollup.config.js
└───src
    ├───Components
    │   ...
    └───app.ts
  1. Install tscc cli:
    yarn global add @tscc/tscc
    
  2. Create a spec file tscc.spec.json next to tsconfig.json.
    {
        "modules": {
            "out": "src/app.ts" // entry file path
        }
    }
    
  3. Execute at the project root:
    tscc
    

In order to setup an alternative rollup build,

  1. In your project's directory, install @tscc/rollup-plugin-tscc by executing:
    yarn add -D @tscc/rollup-plugin-tscc
    
  2. Import rollup-plugin-tscc plugin in rollup config file.
    // rollup.config.js
    import tscc from '@tscc/rollup-plugin-tscc';
    export default {
        output: {
            ...,
            dir: '.'
        },
        plugins: [
            tscc(),
            typescript()
        ]
    }
    
  3. Execute rollup at the project root.

Usage

Command line

@tscc/tscc package provides a single command line interface tscc.

tscc [--help] [--clean] [--spec <spec_file_path>] [-- <typescript_flags> [-- <closure_compiler_flags>]]

It will compile & bundle typescript sourced based on module spec described in spec_file. Alternatively, one can provide the spec file's key-value pairs via command line arguments, see below. Note that one have to provide a spec file or at least a value for a 'module' - if both are omitted, it will assume that the spec file's path is implicitly set as the current working directory.

Arguments passed after the first --, if exists, will be passed to the typescript compiler as one would pass to tsc, and arguments after the second -- will be passed to the closure compiler. e.g. tscc --spec src -- --target ES5 -- --assume_function_wrapper. Note that tsc assumes that the project root (--project) is the current working directory when it is omitted, but tscc assumes that it is the containing directory of the spec file.

JS API

Simply provide contents of spec file as an argument:

import tscc from 'tscc';

tscc({
    modules: {
        bundle: 'entry.ts'
    },
    prefix: 'dist/'
    // ...
}).then(() => console.log('Done'));

The default export tscc function accepts up to 3 arguments.

tscc(
    json_content_of_spec_file_or_path_to_spec_file,
    path_to_search_for_tsconfig?:string,
    typescript_compiler_option_override?
):Promise<void>

The first argument is either a string representing the path of the spec file or a JSON content of the spec file. The JSON object can additionally have specFile property, whose value is a path to a spec file. TSCC will lookup tscc spec file at that path and merge its contents.

tscc({
    /* Contents of spec JSON */
    specFile: "path_to_spec_file.json"
})
// To load spec file from the path and override it.

The second argument should be self-explanatory; the third argument is what would you put in tsconfig.json's "compilerOption" key, it will override those provided with the second argument.

Usage with rollup

@tscc/rollup-plugin-tscc package provides a rollup plugin which will provide chunking information in your spec file to rollup.

Install rollup-plugin-tscc by executing yarn add -D @tscc/rollup-plugin-tscc.

// rollup.config.js
const tscc = require('@tscc/rollup-plugin-tscc');
module.exports = {
    output: {
        dir: '.' // output.dir option will be provided by the plugin, but
                 // rollup currently requires something to be present in order to
                 // work properly.
    },
    // ...
    plugins: [
        tscc({
            /* Contents of spec JSON */
            // or,
            specFile: "path_to_spec_file.json"
        })
    ]
};

Then it will provide the information in your spec file to rollup, and post-process code-splitting chunks produced by rollup to match the behavior of Closure Compiler, so that you can use rollup build interchangeably with tscc build. The plugin will control the input, output.dir, output.entryFileNames, output.chunkFileNames option. Note that it does not transpile TS to JS, one has to provide another plugin manually, such as rollup-plugin-typescript2.

Tscc spec files

Tscc spec file is a single source of truth of your bundling information. It describes each of output bundle's entry file and dependencies among them. It also describes which modules imported in your source shall be treated as an external module and aliased with which global variable.

{
    modules, /* required */
    external,
    prefix,
    chunkFormat,
    compilerFlags,
    jsFiles,
    debug
}

modules

    "modules": {
        "index": "index.ts",
        "dependent_a": {
            "entry": "dependent_a_entry_file.ts",
            "dependencies": [ "index" ],
            "extraSources": [ "css_renaming_map.js" ]
        }
    }

modules option is a key-value pair of module name and module's specification. If a specification only consists of a entry file name, it can simply be a string representing the entry file's path, which is sufficient for most of build situation where no code splitting is applied. In general, module's specification consists of entry, dependencies, and extraSources. dependencies is an array of module names that this module depends on. It can be omitted if empty. Module names specified here will be provided to closure compiler via --chunk flags, so check out a more detailed description of it in Closure Compiler repo. extraSources is an array of file names, which are not included in the Typescript project or not reacheable from a specified entry file via imports, but still needed to be provided to the closure compiler, such as css renaming maps generated by Closure Stylesheets. It can be omitted if empty. A module's name is an identifier to be used as a output chunk's name. To control the output directory, use prefix option.

CLI equivalent is --module <module_name>:<entry_file>:<comma_separated_dependencies>:<comma_separated_extra_sources>.

external

{
    "external": {
        "react": "React",
        "react-dom": "ReactDOM",
    }
}

It is mostly identical to the output.global option of rollup. It is a key-value pair, where key is a module name whose content w

View on GitHub
GitHub Stars166
CategoryDevelopment
Updated1mo ago
Forks10

Languages

TypeScript

Security Score

100/100

Audited on Feb 25, 2026

No findings