modularize bundler and minify scripts
This commit is contained in:
parent
639967c767
commit
89492a4956
8 changed files with 173 additions and 124 deletions
87
bundler/bundle.js
Normal file
87
bundler/bundle.js
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
"use strict"
|
||||||
|
|
||||||
|
var fs = require("fs")
|
||||||
|
var path = require("path")
|
||||||
|
|
||||||
|
module.exports = function(input, output) {
|
||||||
|
function run(e, file) {
|
||||||
|
var modules = {}
|
||||||
|
var usedVariables = {}
|
||||||
|
|
||||||
|
function resolve(dir, data) {
|
||||||
|
var replacements = []
|
||||||
|
data = data.replace(/((?:var|let|const|)[\t ]*)([\w_$\.]+)(\s*=\s*)require\(([^\)]+)\)/g, function(match, def, variable, eq, dep) {
|
||||||
|
usedVariables[variable] = usedVariables[variable] ? usedVariables[variable]++ : 1
|
||||||
|
|
||||||
|
var filename = new Function("return " + dep).call()
|
||||||
|
|
||||||
|
//resolve npm dependencies
|
||||||
|
if (filename[0] !== ".") {
|
||||||
|
var meta = JSON.parse(fs.readFileSync("./node_modules/" + filename + "/package.json"))
|
||||||
|
var dependencyEntry = "./node_modules/" + filename + "/" + (meta.main || filename + ".js")
|
||||||
|
try {fs.statSync(dependencyEntry).isFile()} catch (e) {dependencyEntry = "./node_modules/" + filename + "/index.js"}
|
||||||
|
return resolve(path.dirname(dependencyEntry), exportCode(dependencyEntry, def + variable + eq))
|
||||||
|
}
|
||||||
|
|
||||||
|
//resolve local dependencies
|
||||||
|
var normalized = path.resolve(dir, filename)
|
||||||
|
var pathname = path.dirname(normalized)
|
||||||
|
if (modules[normalized] === undefined) {
|
||||||
|
modules[normalized] = variable
|
||||||
|
var exported = exportCode(dir + "/" + filename + ".js", def + variable + eq)
|
||||||
|
return resolve(pathname, exported)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (modules[normalized] !== variable) {
|
||||||
|
replacements.push({variable: variable, replacement: modules[normalized]})
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (replacements.length > 0) {
|
||||||
|
for (var i = 0; i < replacements.length; i++) {
|
||||||
|
data = data.replace(new RegExp("\\b" + replacements[i].variable + "\\b", "g"), replacements[i].replacement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
.replace(/(?:var|let|const)[\t ]([\w_$\.]+)(\s*=\s*)\1([\r\n;]+)/g, "$3") // remove assignments to itself
|
||||||
|
.replace(/([\r\n]){2,}/g, "$1") // remove multiple consecutive line breaks
|
||||||
|
.replace(/\}[\r\n]+\(/g, "}(") // remove space from iife
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportCode(file, assignment) {
|
||||||
|
return fixCollisions(fs.readFileSync(file, "utf8"))
|
||||||
|
.replace(/("|')use strict\1;?\s*/gm, "") // remove extraneous "use strict"
|
||||||
|
.replace(/module\.exports\s*=\s*/gm, assignment)
|
||||||
|
}
|
||||||
|
|
||||||
|
function fixCollisions(code) {
|
||||||
|
for (var variable in usedVariables) {
|
||||||
|
var collision = new RegExp("\\b" + variable + "\\b(?![\"'`])", "g")
|
||||||
|
var exported = new RegExp("module\\.exports\\s*=\\s*" + variable)
|
||||||
|
if (collision.test(code) && !exported.test(code)) {
|
||||||
|
var fixed = variable + usedVariables[variable]++
|
||||||
|
code = code.replace(collision, fixed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
|
function setVersion(code) {
|
||||||
|
var metadata = JSON.parse(fs.readFileSync("./package.json"))
|
||||||
|
return code.replace("bleeding-edge", metadata.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
function bundle(input, output) {
|
||||||
|
console.log("bundling...")
|
||||||
|
var code = setVersion(resolve(path.dirname(input), fs.readFileSync(input, "utf8")))
|
||||||
|
if (new Function(code)) fs.writeFileSync(output, code, "utf8")
|
||||||
|
console.log("done")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file !== output && file !== output.replace(/\.js$/, ".min.js")) bundle(input, output)
|
||||||
|
}
|
||||||
|
run()
|
||||||
|
|
||||||
|
//fs.watch(process.cwd(), {recursive: true}, run)
|
||||||
|
}
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
"use strict"
|
|
||||||
|
|
||||||
var fs = require("fs")
|
|
||||||
var path = require("path")
|
|
||||||
|
|
||||||
var modules = {}
|
|
||||||
var usedVariables = {}
|
|
||||||
|
|
||||||
function resolve(dir, data) {
|
|
||||||
var replacements = []
|
|
||||||
data = data.replace(/((?:var|let|const|)[\t ]*)([\w_$\.]+)(\s*=\s*)require\(([^\)]+)\)/g, function(match, def, variable, eq, dep) {
|
|
||||||
usedVariables[variable] = usedVariables[variable] ? usedVariables[variable]++ : 1
|
|
||||||
|
|
||||||
var filename = new Function("return " + dep).call()
|
|
||||||
|
|
||||||
//resolve npm dependencies
|
|
||||||
if (filename[0] !== ".") {
|
|
||||||
var meta = JSON.parse(fs.readFileSync("./node_modules/" + filename + "/package.json"))
|
|
||||||
var dependencyEntry = "./node_modules/" + filename + "/" + (meta.main || filename + ".js")
|
|
||||||
try {fs.statSync(dependencyEntry).isFile()} catch (e) {dependencyEntry = "./node_modules/" + filename + "/index.js"}
|
|
||||||
return resolve(path.dirname(dependencyEntry), exportCode(dependencyEntry, def + variable + eq))
|
|
||||||
}
|
|
||||||
|
|
||||||
//resolve local dependencies
|
|
||||||
var normalized = path.resolve(dir, filename)
|
|
||||||
var pathname = path.dirname(normalized)
|
|
||||||
if (modules[normalized] === undefined) {
|
|
||||||
modules[normalized] = variable
|
|
||||||
var exported = exportCode(dir + "/" + filename + ".js", def + variable + eq)
|
|
||||||
return resolve(pathname, exported)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (modules[normalized] !== variable) {
|
|
||||||
replacements.push({variable: variable, replacement: modules[normalized]})
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (replacements.length > 0) {
|
|
||||||
for (var i = 0; i < replacements.length; i++) {
|
|
||||||
data = data.replace(new RegExp("\\b" + replacements[i].variable + "\\b", "g"), replacements[i].replacement)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
.replace(/(?:var|let|const)[\t ]([\w_$\.]+)(\s*=\s*)\1([\r\n;]+)/g, "$3") // remove assignments to itself
|
|
||||||
.replace(/([\r\n]){2,}/g, "$1") // remove multiple consecutive line breaks
|
|
||||||
.replace(/\}[\r\n]+\(/g, "}(") // remove space from iife
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportCode(file, assigment) {
|
|
||||||
return fixCollisions(fs.readFileSync(file, "utf8"))
|
|
||||||
.replace(/("|')use strict\1;?\s*/gm, "") // remove extraneous "use strict"
|
|
||||||
.replace(/module\.exports\s*=\s*/gm, assigment)
|
|
||||||
}
|
|
||||||
|
|
||||||
function fixCollisions(code) {
|
|
||||||
for (var variable in usedVariables) {
|
|
||||||
var collision = new RegExp("\\b" + variable + "\\b(?![\"'`])", "g")
|
|
||||||
var exported = new RegExp("module\\.exports\\s*=\\s*" + variable)
|
|
||||||
if (collision.test(code) && !exported.test(code)) {
|
|
||||||
var fixed = variable + usedVariables[variable]++
|
|
||||||
code = code.replace(collision, fixed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
|
|
||||||
function setVersion(code) {
|
|
||||||
var metadata = JSON.parse(fs.readFileSync("./package.json"))
|
|
||||||
return code.replace("bleeding-edge", metadata.version)
|
|
||||||
}
|
|
||||||
|
|
||||||
function bundle(input, output) {
|
|
||||||
var code = setVersion(resolve(".", fs.readFileSync(input, "utf8")))
|
|
||||||
if (new Function(code)) fs.writeFileSync(output, code, "utf8")
|
|
||||||
}
|
|
||||||
|
|
||||||
bundle("index.js", "mithril.js")
|
|
||||||
21
bundler/cli.js
Normal file
21
bundler/cli.js
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
"use strict"
|
||||||
|
|
||||||
|
var bundle = require("./bundle")
|
||||||
|
var minify = require("./minify")
|
||||||
|
|
||||||
|
var aliases = {o: "output"}
|
||||||
|
var params = {}
|
||||||
|
var args = process.argv.slice(2), command = null
|
||||||
|
console.log(args)
|
||||||
|
for (var i = 0; i < args.length; i++) {
|
||||||
|
if (args[i][0] === '"') args[i] = args[i].slice(1, -1)
|
||||||
|
if (args[i][0] === "-") command = args[i].replace(/\-+/g, "")
|
||||||
|
else if (command != null) {
|
||||||
|
params[aliases[command] || command] = args[i]
|
||||||
|
command = null
|
||||||
|
}
|
||||||
|
else params.input = args[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
bundle(params.input, params.output)
|
||||||
|
minify(params.output, params.output.replace(/\.js$/, ".min.js"))
|
||||||
|
|
@ -2,48 +2,64 @@ var http = require("http")
|
||||||
var querystring = require("querystring")
|
var querystring = require("querystring")
|
||||||
var fs = require("fs")
|
var fs = require("fs")
|
||||||
|
|
||||||
var code = fs.readFileSync("./mithril.js", "utf8")
|
module.exports = function(input, output) {
|
||||||
|
function format(n) {
|
||||||
var data = {
|
return n.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
|
||||||
output_format: "json",
|
|
||||||
output_info: ["compiled_code", "warnings", "errors", "statistics"],
|
|
||||||
compilation_level: "SIMPLE_OPTIMIZATIONS",//ADVANDED_OPTIMIZATIONS
|
|
||||||
warning_level: "default",
|
|
||||||
output_file_name: "default.js",
|
|
||||||
js_code: code,
|
|
||||||
}
|
|
||||||
|
|
||||||
var body = querystring.stringify(data)
|
|
||||||
|
|
||||||
var req = http.request({
|
|
||||||
method: "POST",
|
|
||||||
protocol: "http:",
|
|
||||||
hostname: "closure-compiler.appspot.com",
|
|
||||||
path: "/compile",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
|
|
||||||
"Content-Length": body.length
|
|
||||||
}
|
}
|
||||||
}, function(res) {
|
|
||||||
res.on("data", function(chunk) {
|
|
||||||
response += chunk.toString()
|
|
||||||
})
|
|
||||||
res.on("end", function() {
|
|
||||||
var results = JSON.parse(response)
|
|
||||||
var stats = results.statistics
|
|
||||||
console.log("Original size: " + format(stats.originalGzipSize) + " bytes gzipped (" + format(stats.originalSize) + " bytes uncompressed)")
|
|
||||||
console.log("Compiled size: " + format(stats.compressedGzipSize) + " bytes gzipped (" + format(stats.compressedSize) + " bytes uncompressed)")
|
|
||||||
|
|
||||||
fs.writeFileSync("mithril.min.js", results.compiledCode, "utf8")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
var response = ""
|
function minify(input, output) {
|
||||||
|
var code = fs.readFileSync(input, "utf8")
|
||||||
|
|
||||||
req.write(body)
|
var data = {
|
||||||
req.end()
|
output_format: "json",
|
||||||
console.log("compiling...")
|
output_info: ["compiled_code", "warnings", "errors", "statistics"],
|
||||||
|
compilation_level: "SIMPLE_OPTIMIZATIONS",//ADVANDED_OPTIMIZATIONS
|
||||||
|
warning_level: "default",
|
||||||
|
output_file_name: "default.js",
|
||||||
|
js_code: code,
|
||||||
|
}
|
||||||
|
|
||||||
function format(n) {
|
var body = querystring.stringify(data)
|
||||||
return n.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
|
|
||||||
}
|
var response = ""
|
||||||
|
var req = http.request({
|
||||||
|
method: "POST",
|
||||||
|
protocol: "http:",
|
||||||
|
hostname: "closure-compiler.appspot.com",
|
||||||
|
path: "/compile",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
|
||||||
|
"Content-Length": body.length
|
||||||
|
}
|
||||||
|
}, function(res) {
|
||||||
|
res.on("data", function(chunk) {
|
||||||
|
response += chunk.toString()
|
||||||
|
})
|
||||||
|
res.on("end", function() {
|
||||||
|
var results = JSON.parse(response)
|
||||||
|
if (results.errors) {
|
||||||
|
for (var i = 0; i < results.errors.length; i++) console.log(results.errors[i])
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fs.writeFileSync(output, results.compiledCode, "utf8")
|
||||||
|
|
||||||
|
var stats = results.statistics
|
||||||
|
console.log("done")
|
||||||
|
console.log("Original size: " + format(stats.originalGzipSize) + " bytes gzipped (" + format(stats.originalSize) + " bytes uncompressed)")
|
||||||
|
console.log("Compiled size: " + format(stats.compressedGzipSize) + " bytes gzipped (" + format(stats.compressedSize) + " bytes uncompressed)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
req.write(body)
|
||||||
|
req.end()
|
||||||
|
console.log("minifying...")
|
||||||
|
}
|
||||||
|
function run() {
|
||||||
|
minify(input, output)
|
||||||
|
}
|
||||||
|
run()
|
||||||
|
|
||||||
|
//fs.watchFile(input, run)
|
||||||
|
}
|
||||||
|
|
|
||||||
4
index.js
4
index.js
|
|
@ -24,7 +24,9 @@ m.withAttr = require("./util/withAttr")
|
||||||
m.render = renderService.render
|
m.render = renderService.render
|
||||||
m.redraw = redrawService.publish
|
m.redraw = redrawService.publish
|
||||||
|
|
||||||
if (typeof module === "object") module.exports = m
|
if (typeof module === "object") {
|
||||||
|
module.exports = m
|
||||||
|
}
|
||||||
else window.m = m
|
else window.m = m
|
||||||
|
|
||||||
})()
|
})()
|
||||||
|
|
|
||||||
|
|
@ -1048,6 +1048,8 @@ m.withAttr = function(attrName, callback, context) {
|
||||||
}
|
}
|
||||||
m.render = renderService.render
|
m.render = renderService.render
|
||||||
m.redraw = redrawService.publish
|
m.redraw = redrawService.publish
|
||||||
if (typeof module === "object") module.exports = m
|
if (typeof module === "object") {
|
||||||
|
module.exports = m
|
||||||
|
}
|
||||||
else window.m = m
|
else window.m = m
|
||||||
})()
|
})()
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ function traverseDirectory(pathname, callback) {
|
||||||
traverseDirectory(".", function(pathname, stat, children) {
|
traverseDirectory(".", function(pathname, stat, children) {
|
||||||
if (pathname.indexOf("node_modules") > -1) return
|
if (pathname.indexOf("node_modules") > -1) return
|
||||||
if (pathname.match(/(?:^|\/)tests\/.*\.js$/)) {
|
if (pathname.match(/(?:^|\/)tests\/.*\.js$/)) {
|
||||||
require("../../" + pathname)
|
require(path.normalize(process.cwd()) + "/" + pathname)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(o.run)
|
.then(o.run)
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "node bundler/bundler",
|
"build": "node bundler/cli index.js -o mithril.js",
|
||||||
"minify": "node bundler/minify",
|
|
||||||
"lintdocs": "node bundler/lintdocs",
|
"lintdocs": "node bundler/lintdocs",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"test": "node ospec/bin/ospec",
|
"test": "node ospec/bin/ospec",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue