easy life
- Dominant language
- JavaScript
- Stars
- 119
- Forks
- 11
- PR merge metrics
- No merged PRs in 30d
Description
enableLegacyBabel5ModuleInterop: true is good with browserify
there's a prod mode setting for sucrase also, i suppose its a free envify
at least 10x less memory use than webpack, sadly that a true statement lol
```js
var stream = require("stream");
var util = require("util");
var path = require("path");
let sucrase = require("sucrase")
module.exports = buildTransform();
module.exports.configure = buildTransform;
/** @type import('sucrase').Options */
var sucraseConfig = file => ({
transforms: ["typescript", "imports", "jsx"],
filePath: file,
//enableLegacyTypeScriptModuleInterop: true
enableLegacyBabel5ModuleInterop: true
})
/** @type import('sucrase').Options */
var sucraseHotConfig = file => ({
transforms: ["typescript", "imports", "jsx", "react-hot-loader"],
filePath: file,
//enableLegacyTypeScriptModuleInterop: true
enableLegacyBabel5ModuleInterop: true
})
function buildTransform() {
return function (filename) {
const babelOpts = sucraseConfig(filename)
if (babelOpts === null) {
return stream.PassThrough();
}
return new SucraseStream(babelOpts);
};
}
class SucraseStream extends stream.Transform {
constructor(opts) {
super();
this._data = [];
this._opts = opts;
}
_transform(buf, enc, callback) {
this._data.push(buf);
callback();
}
_flush(callback) {
// Merge the buffer pieces after all are available
const data = Buffer.concat(this._data).toString();
try{
let result = sucrase.transform(data, this._opts)
var code = result !== null ? result.code : data;
this.push(code);
callback();
}
catch(e){
callback(e)
}
}
}
```
you can use this to auto alias everything in src (or wherever, easy to change) so you can use absolute paths np. I suppose you could do some charCode string checks for 'react' to replace with 'preact' or something like that, but meh.
```
var path = require('path')
const { Transform, PassThrough } = require('stream')
/** type{(file: ReadonlyArray, dir: string)}*/
function parseImports(file, dir) {
const results = file.map((line, index) => {
const imports = findImport(line);
if (imports === null) {
return null;
}
return {
path: dir,
index,
import: imports,
};
});
return results.filter((value) => {
return value !== null && value !== undefined;
});
}
/**
* @type{(line: string)}
* @returns {string | null}
*/
function findImport(line) {
const matches = line.match(/from (["'])(.*?)\1/) || line.match(/import\((["'])(.*?)\1\)/) || line.match(/require\((["'])(.*?)\1\)/);
if (!matches) {
return null;
}
const multiple = [/from (["'])(.*?)\1/g, /import\((["'])(.*?)\1\)/g, /require\((["'])(.*?)\1\)/g].some((exp) => {
const results = line.match(exp);
//console.log(results)
//
//return results && results.length > 1
if (results && results.length > 1) {
results.map(r => findImport(r))
}
})
// if (multiple) {
//throw new Error('Multiple imports on the same line are currently not supported!');
//jk fixed with recursion
// }
return matches[2];
}
/** @type {(file: ReadonlyArray, imports: FileData[], options: CompilerOptions) => string[]) }
* @returns : string[]
*/
function resolveImports(file, imports, options) {
const { baseUrl, paths } = options;
/** @type { [key: string]: string[] | undefined } */
const aliases = {};
for (const alias in paths) {
/* istanbul ignore else */
if (paths.hasOwnProperty(alias)) {
let resolved = alias;
if (alias.endsWith('/*')) {
resolved = alias.replace('/*', '/');
}
aliases[resolved] = paths[alias];
}
}
const lines = [...file];
for (const imported of imports) {
const line = file[imported.index];
let resolved = '';
for (const alias in aliases) {
/* istanbul ignore else */
if (aliases.hasOwnProperty(alias) && imported.import.startsWith(alias)) {
const choices = aliases[alias];
if (choices != undefined) {
resolved = choices[0];
if (resolved.endsWith('/*')) {
resolved = resolved.replace('/*', '/');
}
resolved = imported.import.replace(alias, resolved);
break;
}
}
}
if (resolved.length < 1) {
continue;
}
let relative = path.relative(path.dirname(imported.path), baseUrl || './');
relative = path.join(relative, resolved);
relative = path.relative(path.dirname(imported.path), path.resolve(path.dirname(imported.path), relative));
relative = relative.replace(/\\/g, '/');
if (relative.length === 0 || !relative.startsWith('.')) {
relative = './' + relative;
}
lines[imported.index] = line.replace(imported.import, relative);
}
return lines;
}
const fs = require('fs')
const sourceDirs = fs.readdirSync('src').filter(f => (f.indexOf(".") < 1))
let createConfig = () => {
//todo , merge this with fs read tsconfig + user options + maybe like a web_modules
const config = {
baseUrl: ".",
paths: {}
}
for (var x of sourceDirs) {
config.paths[`${x}/*`] = [`src/${x}/*`]
}
//return JSON.stringify(config)
return config
}
const compilerOptions = createConfig()
function compile(filePath, chunk) {
//const lines = chunk.toString('utf8').split('\n');
const lines = chunk.split('\n');
const imports = parseImports(lines, filePath)
const code = resolveImports(lines, imports, compilerOptions).join('\n')
return code
}
const unpathifyStream = (file) => {
if (!/\.tsx?$|\.jsx?$/.test(file) || file.indexOf("node_modules") > 0 || file.indexOf("src") < 0) {
return new PassThrough();
}
var _transform = new Transform()
_transform._write = (chunk, encoding, next) => {
_transform.push(compile(file, chunk.toString('utf8')))
next();
}
return _transform
}
module.exports = unpathifyStream
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reviewing the repository entry point and the existing transform pipeline; the issue only identifies src as the directory to process and provides proposed Sucrase and import-aliasing code. Clarify whether both transformations are in scope, then define behavior and tests with maintainers before implementing anything.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- build-system, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100