Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sunderls committed Apr 6, 2017
1 parent 6f55f00 commit 6d1955d
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
node_modules
42 changes: 42 additions & 0 deletions example/dist/bundle.js
@@ -0,0 +1,42 @@

(function(moduleFactories) {
// all modules should be instantiated lazily
var modules = [];

function require(id) {
if (modules[id]) {
return modules[id];
} else {
var m = moduleFactories[id]({}, require);
modules.push(m);
return modules[id];
}
}

// kick
require(2);
})([function(exports, require){
exports.log = function(){
console.log('ModuleB log()');
}

return exports; }
,function(exports, require){
var logB = require(0)['log'];

exports.default = {
log() {
console.log('ModuleA log()');
logB();
}
}

return exports; }
,function(exports, require){
var A = require(1)['default'];

console.log('in enty js');
A.log();

return exports; }
])
9 changes: 9 additions & 0 deletions example/dist/index.html
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>lspack demo</title>
</head>
<body>
<script src="./bundle.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion example/lspack.config.js
@@ -1,4 +1,4 @@
{
module.exports = {
entry: './src/index.js',
output: './dist/bundle.js'
}
2 changes: 1 addition & 1 deletion example/src/moduleB.js
@@ -1,3 +1,3 @@
export log = () => {
export function log(){
console.log('ModuleB log()');
}
114 changes: 114 additions & 0 deletions index.js 100644 → 100755
@@ -0,0 +1,114 @@
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const esprima = require('esprima');
const escodegen = require('escodegen');


// add .js to modulePath if not there
// support only relative paths now
const resolveModulePath = (modulePath, relativeTo = '.') => {
return path.resolve(relativeTo, /\.\w+$/.test(modulePath) ? modulePath : modulePath + '.js');
}

const modulePaths = [];
const moduleTexts = [];

// get module's ID
// push into modules if not found
const getModuleId = (modulePath) => {
const id = modulePaths.indexOf(modulePath);
if (id === -1) {
return transform(modulePath);
}

return id;
}

// transform a file to module
// 1. read file text
// 2. get imports & transform recursively
// 3. return index
const transform = (modulePath) => {
const transformedResult = [
'function(exports, require){'
];

// read file from entry
const fileText = fs.readFileSync(modulePath, {
encoding: 'utf8'
});

// use esprima to detect import statement
const program = esprima.parse(fileText, { sourceType: 'module'});

// handle import & export
program.body.forEach(line => {
switch (line.type) {
case 'ImportDeclaration':
const id = getModuleId(resolveModulePath(line.source.value, path.dirname(modulePath)));

line.specifiers.forEach(specifier => {
// [TODO] more types
switch (specifier.type) {
case 'ImportDefaultSpecifier':
transformedResult.push(`var ${specifier.local.name} = require(${id})['default'];\n`);
break;
case 'ImportSpecifier':
transformedResult.push(`var ${specifier.local.name} = require(${id})['${specifier.imported.name}'];\n`);
break;
}
});
break;
case 'ExportDefaultDeclaration':
// export default {}
if (line.declaration.type === 'ObjectExpression') {
transformedResult.push(`exports.default = ${escodegen.generate(line.declaration)}`);
break;
}
case 'ExportNamedDeclaration':
if (line.declaration.type === 'FunctionDeclaration') {
transformedResult.push(`exports.${line.declaration.id.name} = function()${escodegen.generate(line.declaration.body)}`);
break;
}
// [TODO] more types
default:
transformedResult.push(escodegen.generate(line));
}
});
transformedResult.push('\nreturn exports; }\n');

moduleTexts.push(transformedResult.join('\n'));
modulePaths.push(modulePath);
return moduleTexts.length - 1;
};



// read lspack.config.js and parse
const config = require(path.resolve('./lspack.config.js'));
const entryModuleId = transform(resolveModulePath(config.entry));

// we've get all modules, now bootstrap
const bundle = `
(function(moduleFactories) {
// all modules should be instantiated lazily
var modules = [];
function require(id) {
if (modules[id]) {
return modules[id];
} else {
var m = moduleFactories[id]({}, require);
modules.push(m);
return modules[id];
}
}
// kick
require(${entryModuleId});
})([${moduleTexts.join(',')}])
`;

// write to dist
fs.writeFileSync(config.output, bundle);
8 changes: 7 additions & 1 deletion package.json
Expand Up @@ -3,6 +3,7 @@
"version": "0.0.1",
"description": "lspack",
"main": "index.js",
"bin": "./index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
Expand All @@ -15,5 +16,10 @@
"bugs": {
"url": "https://github.com/sunderls/lspack/issues"
},
"homepage": "https://github.com/sunderls/lspack#readme"
"homepage": "https://github.com/sunderls/lspack#readme",
"devDependencies": {
"escodegen": "^1.8.1",
"esprima": "^3.1.3",
"npm": "^4.4.4"
}
}

0 comments on commit 6d1955d

Please sign in to comment.