Skip to content

Commit

Permalink
feat: improve build system and stability
Browse files Browse the repository at this point in the history
  • Loading branch information
pooya parsa committed Jun 7, 2020
1 parent a886f61 commit 5c3ee63
Show file tree
Hide file tree
Showing 10 changed files with 2,851 additions and 261 deletions.
28 changes: 12 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
# jiti

Require with just-in-time compiler for typescript and esm files
Just-in-time compiler for typescript and esm files for CommonJS environments.

## Features

- Stable support for typescript and esm syntax
- Provide sync interface to use inplace of `esm` or `require`
- Super slim and zero dependency (~1.8M install size)
- Works with CJS cache
- [ ] Filesystem caching
- [ ] Syntax detect to avoid extra transforms
- Stable typescript and esm syntax support (currently using babel)
- Provide sync interface to replace `require()` and `esm()`
- Super slim and zero dependency (~1M install size)
- Syntax detect to avoid extra transform
- CommonJS cache integration

## Usage

Expand All @@ -19,10 +18,6 @@ const jiti = require('jiti')(__filename)
jiti('./path/to/file.ts')
```

## How it works

Transform is based on babel and babel-preset-env

## Development

- Clone Repo
Expand All @@ -34,11 +29,12 @@ Transform is based on babel and babel-preset-env
## Roadmap

- [x] Basic working
- [ ] File based caching
- [ ] Syntax detect and fallback to CJS require
- [ ] Configurable transform
- [ ] Try sourcemap improvements
- [ ] Simplify project build system
- [x] Syntax detect and fallback to CJS require
- [x] Improve project build system
- [ ] Sourcemap support
- [ ] File system cache
- [ ] Add tests
- [ ] Configurable transform (esbuild)

## License

Expand Down
27 changes: 13 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,36 @@
"version": "0.1.1",
"description": "",
"license": "MIT",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"main": "dist/jiti.js",
"types": "dist/jiti.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "yarn build:transform && yarn build:jit",
"dev": "yarn build:jit --watch",
"build:jit": "rollup -c",
"build:transform": "ncc build src/transform.ts -t -m -o dist/transform",
"build": "yarn clean && NODE_ENV=production yarn webpack",
"build:babel": "ncc build src/babel.ts -t -m -o dist/babel",
"clean": "rm -rf dist",
"dev": "yarn clean && yarn webpack --watch",
"lint": "eslint --ext .ts,.js .",
"release": "yarn test && yarn build && yarn standard-version && git push --follow-tags && npm publish",
"test": "yarn lint"
},
"devDependencies": {
"@babel/core": "^7.10.2",
"@babel/plugin-transform-typescript": "^7.10.1",
"@babel/preset-env": "^7.10.2",
"@babel/preset-typescript": "^7.10.1",
"@nuxtjs/eslint-config-typescript": "^2.0.0",
"@rollup/plugin-commonjs": "^13.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^8.0.1",
"@types/babel__core": "^7.1.8",
"@types/node": "^14.0.11",
"@zeit/ncc": "^0.22.3",
"create-require": "^1.0.1",
"eslint": "^7.2.0",
"esm": "^3.2.25",
"resolve": "^1.17.0",
"rollup": "^2.13.1",
"rollup-plugin-typescript2": "^0.27.1",
"standard-version": "^8.0.0",
"ts-loader": "^7.0.5",
"tslib": "^2.0.0",
"typescript": "^3.9.5"
"typescript": "^3.9.5",
"webpack": "^5.0.0-beta.17",
"webpack-cli": "^3.3.11"
}
}
27 changes: 0 additions & 27 deletions rollup.config.js

This file was deleted.

6 changes: 2 additions & 4 deletions src/transform.ts → src/babel.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { transformSync } from '@babel/core'
// @ts-ignore
import env from '@babel/preset-env'
import commonjs from '@babel/plugin-transform-modules-commonjs'
// @ts-ignore
import typescript from '@babel/plugin-transform-typescript'

export function transform (source: string): string {
const result = transformSync(source, {
presets: [
[env, { targets: { node: 'current' } }]
],
plugins: [
[commonjs, { allowTopLevelThis: true }],
typescript
]
})?.code || ''
Expand Down
36 changes: 27 additions & 9 deletions src/index.ts → src/jiti.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { readFileSync } from 'fs'
import { Module, builtinModules } from 'module'
import { dirname } from 'path'
import { Script } from 'vm'
import _createRequire from 'create-require'
// @ts-ignore
import resolve from 'resolve'
import { transform } from './babel'

export default function jiti (_filename: string): NodeRequire {
const { transform } = require('./transform')
const _require = _createRequire(_filename)

// https://www.npmjs.com/package/resolve
const resolveOpts = {
extensions: ['.js', '.mjs', '.ts'],
basedir: dirname(_filename)
}
const _resolve = (id: string) => resolve.sync(id, resolveOpts)
_resolve.paths = (_: string) => []

function requireJIT (id: string) {
// Check for builtin node module like fs
Expand All @@ -21,7 +25,7 @@ export default function jiti (_filename: string): NodeRequire {
}

// Resolve path
const filename = resolve.sync(id, resolveOpts)
const filename = _resolve(id)

// Check for CJS cache
if (_require.cache[filename]) {
Expand All @@ -30,35 +34,49 @@ export default function jiti (_filename: string): NodeRequire {

// Read source
let source = readFileSync(filename, 'utf-8')

// Apply transform
source = transform(source)
if (filename.includes('.ts') ||
source.match(/^\s*import .* from/) ||
source.match(/^\s*export /)
) {
// Apply transform
// console.log('>', filename)
source = transform(source)
} else {
// Bail
// console.log('!', filename)
return _require(id)
}

// Compile module
const mod = new Module(filename)
mod.filename = filename
mod.parent = module
mod.require = jiti(filename)

// @ts-ignore
mod.path = dirname(filename)

// @ts-ignore
mod.paths = Module._nodeModulePaths(mod.path)

// Compile module
const wrapped = Module.wrap(source)
const script = new Script(wrapped, { filename })
const compiled = script.runInThisContext({ filename })

// @ts-ignore
mod._compile(source, filename)
compiled.call(mod, mod.exports, mod.require, mod, mod.filename, mod.path)

// Set as loaded
mod.loaded = true

// Set cache entry
// Set CJS cache
_require.cache[filename] = mod

// Return exports
return mod.exports
}

requireJIT.resolve = _require.resolve
requireJIT.resolve = _resolve
requireJIT.cache = _require.cache
requireJIT.extensions = _require.extensions
requireJIT.main = _require.main
Expand Down
9 changes: 9 additions & 0 deletions test/bench/esm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
console.time('esm_init')
const esm = require('esm')(module, { cache: false })
console.timeEnd('esm_init')

for (let i = 0; i < 3; i++) {
console.time('esm_require')
esm('../fixtures/esm').test()
console.timeEnd('esm_require')
}
9 changes: 9 additions & 0 deletions test/bench/jiti.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
console.time('jiti_init')
const jiti = require('../..')(__filename)
console.timeEnd('jiti_init')

for (let i = 0; i < 3; i++) {
console.time('jiti_require')
jiti('../fixtures/esm').test()
console.timeEnd('jiti_require')
}
1 change: 0 additions & 1 deletion test/jiti.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const jiti = require('..')(__filename)

console.log(jiti('./fixtures/esm').test())
console.log(jiti('./fixtures/typescript').test())
43 changes: 43 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const path = require('path')

const isProd = process.env.NODE_ENV === 'production'

module.exports = {
target: 'node',
mode: isProd ? 'production' : 'development',
entry: {
jiti: './src/jiti.ts'
},
devtool: false,
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'commonjs2',
libraryExport: 'default'
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
stats: {
// preset: 'detailed',
warningsFilter: [/critical dependency:/i]
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
node: false,
optimization: {
nodeEnv: false,
moduleIds: 'named',
chunkIds: 'named',
splitChunks: {
chunks: 'all'
}
}
}
Loading

0 comments on commit 5c3ee63

Please sign in to comment.