6

I am writing a GreaseMonkey plugin in TypeScript. I am compiling main.ts file into main.js, and then put it on GreaseMonkey. The output file format looks like vanilla JavaScript, and GreaseMonkey consumes it happily. Now the project grows larger, I plan to split the code into several files. However, I failed to find a build system that works.

Requirements:

  • It should bundle everything into a single JavaScript file. GreaseMonkey only takes one file.
  • It should generate vanilla JavaScript. I don't think things like System.import works in GreaseMonkey.

Possible behavior

Given

// lib.ts
export function greet(name: string) {
    console.log(`Hello, ${ name }!`);
}

and

// main.ts
import { greet } from './lib.ts';

greet("Tom");

it returns

// main.js
let lib_public = {};
lib_public.greet = function greet(name: string) {
    console.log(`Hello, ${ name }!`);
}
lib_public.greet("Tom");
6

Webpack is all you need! OK, some plugins here and there(webpack, webpack-cli, typescript for obvious reasons, ts-loader for webpack-Typescript interaction/compilation), but here is the recipe, assuming your code is in src folder (Main.ts being the entry point) and you want your lib.user.js in dist folder:

webpack.config.js

// required for path resolution for dist folder
const path = require("path");
// used to access the BannerPlugin
const webpack = require("webpack");
// required for pretty format for the Userscript banner
const stripIndent = require("common-tags").stripIndent;

module.exports = {
    entry: "./src/Main.ts",
    devtool: 'inline-source-map',
    mode: "development",
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            }
        ]
    },
    resolve: {
        extensions: [".ts", ".js"]
    },
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "lib.user.js"
    },
    plugins: [
        new webpack.BannerPlugin({
            raw: true,
            banner: stripIndent`
                // ==UserScript==
                // @name    Your lib name
                // @namespace   https://path.com/your/lib/namespace
                // @version 1.0.0
                // @author  Your Name
                // @description Your lib description
                // @include https://www.example.com/*
                // @copyright   2019, Your Org
                // ==/UserScript==`
        })
    ]
};

Important bits from package.json:

  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "common-tags": "^1.8.0",
    "ts-loader": "^5.3.3",
    "typescript": "^3.3.1",
    "webpack": "^4.29.3",
    "webpack-cli": "^3.2.3"
  }

Build: npm run build, which will invoke webpack, as instructed in the scripts section of package.json.

2

Another option is rollup. It allows compiling into one file (using iife)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.