Skip to content

Commit

Permalink
feat: Support for import without lib or es6 (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
Malte Legenhausen authored Jul 22, 2021
1 parent 674a2ac commit 02b8f08
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 21 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/.idea
/node_modules
/dist
/es6
72 changes: 63 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 15 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,45 @@
"typings": "dist/index.d.ts",
"sideEffects": false,
"scripts": {
"build": "tsc -p ./tsconfig.build.json && tsc -p ./tsconfig.es6.json",
"build": "tsc -p ./tsconfig.build.json && tsc -p ./tsconfig.es6.json && npm run import-path-rewrite && ts-node scripts/build",
"test": "npm run tslint && npm run prettier && npm run jest",
"tslint": "tslint -c tslint.json --project tsconfig.json './src/**/*.ts'",
"jest": "jest",
"prettier": "prettier --list-different \"./src/**/*.ts\"",
"prettier:fix": "prettier --write \"./src/**/*.ts\"",
"prepublishOnly": "npm run test && npm run build",
"postbuild": "import-path-rewrite",
"prettier": "prettier --list-different \"./{src,scripts}/**/*.ts\"",
"prettier:fix": "prettier --write \"./{src,scripts}/**/*.ts\"",
"prepublishOnly": "ts-node scripts/pre-publish",
"prerelease": "npm run build",
"import-path-rewrite": "import-path-rewrite",
"release": "ts-node scripts/release",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
"version": "npm run changelog && git add CHANGELOG.md"
},
"author": "devexperts",
"license": "MPL-2.0",
"devDependencies": {
"@devexperts/lint": "^0.29.1",
"@types/glob": "^7.1.3",
"@types/jest": "^22.2.3",
"conventional-changelog-cli": "^2.0.21",
"import-path-rewrite": "github:gcanti/import-path-rewrite",
"jest": "^24.8.0",
"jest-cli": "^24.8.0",
"fp-ts": "^2.5.0",
"glob": "^7.1.7",
"io-ts": "^2.0.0",
"io-ts-types": "^0.5.7",
"prettier": "^1.17.1",
"ts-jest": "^23.10.5",
"tslint": "^5.16.0",
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^1.3.0",
"ts-node": "8.8.2",
"typescript": "^3.5.2"
},
"dependencies": {
"peerDependencies": {
"fp-ts": "^2.0.0",
"io-ts": "^2.0.0",
"io-ts-types": "^0.5.7",
"tslib": "^1.9.3"
"io-ts-types": "^0.5.7"
},
"repository": {
"type": "git",
Expand Down
29 changes: 29 additions & 0 deletions scripts/FileSystem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as TE from 'fp-ts/lib/TaskEither';
import { flow } from 'fp-ts/lib/function';
import * as fs from 'fs';
import G from 'glob';

export interface FileSystem {
readonly readFile: (path: string) => TE.TaskEither<Error, string>;
readonly writeFile: (path: string, content: string) => TE.TaskEither<Error, void>;
readonly copyFile: (from: string, to: string) => TE.TaskEither<Error, void>;
readonly glob: (pattern: string) => TE.TaskEither<Error, ReadonlyArray<string>>;
readonly mkdir: (path: string) => TE.TaskEither<Error, void>;
}

const readFile = TE.taskify<fs.PathLike, string, NodeJS.ErrnoException, string>(fs.readFile);
const writeFile = TE.taskify<fs.PathLike, string, NodeJS.ErrnoException, void>(fs.writeFile);
const copyFile = TE.taskify<fs.PathLike, fs.PathLike, NodeJS.ErrnoException, void>(fs.copyFile);
const glob = TE.taskify<string, Error, ReadonlyArray<string>>(G);
const mkdirTE = TE.taskify(fs.mkdir);

export const fileSystem: FileSystem = {
readFile: path => readFile(path, 'utf8'),
writeFile,
copyFile,
glob,
mkdir: flow(
mkdirTE,
TE.map(() => undefined),
),
};
85 changes: 85 additions & 0 deletions scripts/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import * as path from 'path';
import * as E from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import * as RTE from 'fp-ts/lib/ReaderTaskEither';
import * as A from 'fp-ts/lib/ReadonlyArray';
import * as TE from 'fp-ts/lib/TaskEither';
import { FileSystem, fileSystem } from './FileSystem';
import { run } from './run';

interface Build<A> extends RTE.ReaderTaskEither<FileSystem, Error, A> {}

const OUTPUT_FOLDER = 'dist';
const PKG = 'package.json';

export const copyPackageJson: Build<void> = C =>
pipe(
C.readFile(PKG),
TE.chain(s => TE.fromEither(E.parseJSON(s, E.toError))),
TE.map(v => {
const clone = Object.assign({}, v as any);

delete clone.scripts;
delete clone.files;
delete clone.devDependencies;

return clone;
}),
TE.chain(json => C.writeFile(path.join(OUTPUT_FOLDER, PKG), JSON.stringify(json, null, 2))),
);

export const FILES: ReadonlyArray<string> = ['CHANGELOG.md', 'LICENSE', 'README.md'];

export const copyFiles: Build<ReadonlyArray<void>> = C =>
A.readonlyArray.traverse(TE.taskEither)(FILES, from => C.copyFile(from, path.resolve(OUTPUT_FOLDER, from)));

const traverse = A.readonlyArray.traverse(TE.taskEither);

export const makeModules: Build<void> = C =>
pipe(
C.glob(`${OUTPUT_FOLDER}/lib/*.js`),
TE.map(getModules),
TE.chain(modules => traverse(modules, makeSingleModule(C))),
TE.map(() => undefined),
);

function getModules(paths: ReadonlyArray<string>): ReadonlyArray<string> {
return paths.map(filePath => path.basename(filePath, '.js')).filter(x => x !== 'index');
}

function makeSingleModule(C: FileSystem): (module: string) => TE.TaskEither<Error, void> {
return m =>
pipe(
C.mkdir(path.join(OUTPUT_FOLDER, m)),
TE.chain(() => makePkgJson(m)),
TE.chain(data => C.writeFile(path.join(OUTPUT_FOLDER, m, 'package.json'), data)),
);
}

function makePkgJson(module: string): TE.TaskEither<Error, string> {
return pipe(
JSON.stringify(
{
main: `../lib/${module}.js`,
module: `../es6/${module}.js`,
typings: `../lib/${module}.d.ts`,
sideEffects: false,
},
null,
2,
),
TE.right,
);
}

const main: Build<void> = pipe(
copyPackageJson,
RTE.chain(() => copyFiles),
RTE.chain(() => makeModules),
);

run(
main({
...fileSystem,
}),
);
6 changes: 6 additions & 0 deletions scripts/pre-publish.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { left } from 'fp-ts/lib/TaskEither';
import { run } from './run';

const main = left(new Error('"npm publish" can not be run from root, run "npm run release" instead'));

run(main);
23 changes: 23 additions & 0 deletions scripts/release.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { run } from './run';
import * as child_process from 'child_process';
import { left, right } from 'fp-ts/lib/Either';
import * as TE from 'fp-ts/lib/TaskEither';

const DIST = 'dist';

const exec = (cmd: string, args?: child_process.ExecOptions): TE.TaskEither<Error, void> => () =>
new Promise(resolve => {
child_process.exec(cmd, args, err => {
if (err !== null) {
return resolve(left(err));
}

return resolve(right(undefined));
});
});

export const main = exec('npm publish', {
cwd: DIST,
});

run(main);
21 changes: 21 additions & 0 deletions scripts/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { fold } from 'fp-ts/lib/Either';
import { TaskEither } from 'fp-ts/lib/TaskEither';

export function run<A>(eff: TaskEither<Error, A>): void {
eff()
.then(
fold(
e => {
throw e;
},
_ => {
process.exitCode = 0;
},
),
)
.catch(e => {
console.error(e); // tslint:disable-line no-console

process.exitCode = 1;
});
}
2 changes: 1 addition & 1 deletion tsconfig.es6.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "./tsconfig.build.json",
"compilerOptions": {
"outDir": "./es6",
"outDir": "dist/es6",
"target": "es6",
"module": "es6"
}
Expand Down
5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
"moduleResolution": "node",
"target": "es5",
"lib": ["es6", "dom"],
"outDir": "dist",
"outDir": "dist/lib",
"declaration": true,
"strict": true,
"importHelpers": true,
"pretty": true,
"noUnusedLocals": true,
"noEmitOnError": true
"noEmitOnError": true,
"esModuleInterop": true
},
"include": [
"./src/**/*"
Expand Down

0 comments on commit 02b8f08

Please sign in to comment.