Skip to content

Instantly share code, notes, and snippets.

@julian-a-avar-c
Last active October 26, 2021 23:06
Show Gist options
  • Save julian-a-avar-c/b043579478acd56807ab24aa6559b859 to your computer and use it in GitHub Desktop.
Save julian-a-avar-c/b043579478acd56807ab24aa6559b859 to your computer and use it in GitHub Desktop.
typescript+babel+teser gulpfile. It grabs every `.ts` file in `src` and throws them in `dist`, and transpiles to every module format.
{
"name": "typescript+babel+teser gulpfile",
"license": "MIT",
"author": {
"email": "[email protected]",
"name": "jaacko-torus",
"url": "https://github.com/jaacko-torus"
},
"type": "module",
"engines": {
"node": "^16.12.0"
},
"scripts": {
"dev": "tsc --watch",
"gulp": "yarn gulp.build && yarn gulp.run",
"gulp.build": "tsc --project gulp",
"gulp.run": "gulp"
},
"devDependencies": {
"@babel/cli": "^7.15.7",
"@babel/core": "^7.15.8",
"@babel/plugin-transform-modules-amd": "^7.14.5",
"@babel/plugin-transform-modules-commonjs": "^7.15.4",
"@babel/plugin-transform-modules-systemjs": "^7.15.4",
"@babel/plugin-transform-modules-umd": "^7.14.5",
"@babel/preset-env": "^7.15.8",
"@types/gulp": "^4.0.9",
"@types/gulp-babel": "^6.1.30",
"@types/gulp-rename": "^2.0.1",
"@types/gulp-sourcemaps": "^0.0.35",
"@types/gulp-terser": "^1.2.1",
"@types/node": "^16.11.5",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"gulp-cli": "^2.3.0",
"gulp-rename": "^2.0.0",
"gulp-sourcemaps": "^3.0.0",
"gulp-terser": "^2.1.0",
"gulp-typescript": "^6.0.0-alpha.1",
"typescript": "^4.4.4"
}
}
{
"compilerOptions": {
"alwaysStrict": true,
"esModuleInterop": true,
"module": "ESNext",
"moduleResolution": "Node",
"noImplicitAny": true,
"sourceMap": true,
"isolatedModules": true,
"outDir": "..",
"strict": true,
"target": "ESNext"
},
"include": ["gulpfile.ts"],
"exclude": ["node_modules"]
}
/**
* MIT License (c) 2021 Julian A Avar C
*
* Expected folder structure
*
* project/
* |- src/
* | |- index.ts
* | |- ...
* |- gulp/
* | |- gulpfile.ts
* | |- tsconfig.json
* |- dist/ - auto generated
* |- amd/
* |- cjs/
* |- mjs/
* |- sjs/
* |- umd/
*
* This will generate `.js`, `.map`, and their minified versions for every file under `src`.
*
* gulp tasks
* |- default - only compiles `.ts` and makes `.map` files
* |- minify - only minifies compiled and mapped files
* |- dist - does everything
* |- dev - only does default, but in watch mode
*
* Run `yarn gulp --tasks` for more info.
*/
import gulp from "gulp"
import sourcemaps from "gulp-sourcemaps"
import ts from "gulp-typescript"
import babel from "gulp-babel"
import terser from "gulp-terser"
import rename from "gulp-rename"
type Entry<T> = { [K in keyof T]: [K, T[K]] }[keyof T];
type TaskResult = NodeJS.ReadWriteStream;
type Task = () => TaskResult;
type TaskOptSuffix = { dirname?: string };
type TaskOptTask = { task: Task };
type TaskOpts = TaskOptSuffix & TaskOptTask;
type TaskName = string;
type TaskInfoRecord = { [taskName: TaskName]: TaskOptSuffix };
type TaskRecord = { [taskName: TaskName]: TaskOpts };
const modules: TaskInfoRecord = {
mjs: {},
umd: {},
amd: {},
commonjs: { dirname: "cjs" },
systemjs: { dirname: "sjs" }
};
const task_default = () => {
const taskCallback = ([moduleName, moduleInfoRecord]: Entry<TaskInfoRecord>) => {
const tsResult = gulp
.src(["src/**/*.ts"])
.pipe(sourcemaps.init())
.pipe(ts.createProject("tsconfig.json")());
const applyModuleTransformation = () => moduleName === "mjs"
? tsResult.js
: tsResult.js.pipe(babel({
presets: ["@babel/preset-env"],
plugins: [`@babel/plugin-transform-modules-${moduleName}`]
}))
const babelResult : TaskResult = applyModuleTransformation()
.pipe(rename({ dirname: moduleInfoRecord?.dirname ?? moduleName }));
const taskOpts = { ...moduleInfoRecord, task: () => babelResult };
return [moduleName, taskOpts] as Entry<TaskRecord>;
}
return Object.fromEntries(Object.entries(modules).map(taskCallback)) as TaskRecord;
}
const task_minify = () => {
const taskCallback = ([moduleName, moduleOpts]: Entry<TaskRecord>) => {
const terserResult = moduleOpts.task()
.pipe(rename({ suffix: ".min" }))
.pipe(terser({
ecma: 2015,
compress: true,
mangle: {
toplevel: true,
reserved: ["lox"]
}
}));
return [moduleName, { ...moduleOpts, task: () => terserResult }] as Entry<TaskRecord>;
}
return Object.fromEntries(Object.entries(task_default()).map(taskCallback)) as TaskRecord;
};
function series(taskNames : TaskName[]) {
return gulp.series(taskNames.map(taskName => gulp.task(taskName)));
}
const mapAndWrite = (task : Task) => () => task().pipe(sourcemaps.write(".")).pipe(gulp.dest("dist"));
const makeTasks = (taskSetName : string, taskRecord : TaskRecord) => {
const getTaskName = (taskName : string) => `${taskSetName}_${taskName}`
Object.entries(taskRecord).map(([taskName, taskOpts]) => {
gulp.task(getTaskName(taskName), mapAndWrite(taskOpts.task));
});
gulp.task(taskSetName, series(Object.entries(taskRecord).map(([taskName]) => getTaskName(taskName))));
}
makeTasks("default", task_default());
makeTasks("minify", task_minify());
gulp.task("dist", series(["default", "minify"]));
gulp.task("dev", () => gulp.watch("src/lox.ts", gulp.task("default")));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment