Last active
April 1, 2018 01:58
-
-
Save KevinWang15/dd06c3106ec88535c02b64cca685a647 to your computer and use it in GitHub Desktop.
Upload JS/CSS to qiniu cdn for production in index.html, cache bust according to checksum
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = { | |
qiniu_ak: '', | |
qiniu_sk: '', | |
qiniu_bucket: '', | |
qiniu_domain:'http://cdn.example.com' | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
const INDEX_FILE_NAME = './www/index.html'; | |
const FILE_PREFIX = "_myproject-min-build"; | |
const fs = require('fs'); | |
const path = require('path'); | |
const crypto = require('crypto'); | |
const qiniu = require('qiniu'); | |
const UglifyJS = require("uglify-js"); | |
const CleanCSS = require('clean-css'); | |
const config = require('./config'); | |
const INDEX_DIR = path.dirname(INDEX_FILE_NAME); | |
/** ngAnnotate **/ | |
// const ngAnnotate = require("ng-annotate"); | |
let qiniuConfig = new qiniu.conf.Config(); | |
qiniuConfig.zone = qiniu.zone.Zone_z0; | |
qiniuConfig.useCdnDomain = true; | |
let putExtra = new qiniu.form_up.PutExtra(); | |
let mac = new qiniu.auth.digest.Mac(config.qiniu_ak, config.qiniu_sk); | |
let options = { | |
scope: config.qiniu_bucket, | |
}; | |
let putPolicy = new qiniu.rs.PutPolicy(options); | |
let uploadToken = putPolicy.uploadToken(mac); | |
let bucketManager = new qiniu.rs.BucketManager(mac, qiniuConfig); | |
function getMimeType(fileName) { | |
if (fileName.endsWith('css')) { | |
return 'text/css'; | |
} | |
if (fileName.endsWith('js')) { | |
return 'application/javascript'; | |
} | |
} | |
function upload(fileName, minificationType) { | |
let localFile = path.join(INDEX_DIR, fileName); | |
return new Promise((resolve, reject) => { | |
fs.readFile(localFile, { encoding: 'utf8' }, function (err, data) { | |
if (err) { | |
throw(err); | |
} | |
if (minificationType === "js") { | |
/** ngAnnotate **/ | |
// data = ngAnnotate(data, { | |
// add: true, | |
// }); | |
// if (err || (data.errors && data.errors.length)) { | |
// throw JSON.stringify(err || data.errors); | |
// } | |
// data = data.src; | |
// console.log(data); | |
console.log("minify js: ", fileName); | |
data = UglifyJS.minify(data); | |
if (data.error) { | |
throw data.error; | |
} | |
data = data.code; | |
} else if (minificationType === "css") { | |
console.log("minify css: ", fileName); | |
data = new CleanCSS(options).minify(data); | |
if (data.errors.length) { | |
throw JSON.stringify(data.errors); | |
} | |
data = data.styles; | |
} | |
let cs = checksum(data, 'sha1'); | |
let key = FILE_PREFIX + '-' + cs + '-' + fileName.replace(/[/\\]/g, '_'); | |
let formUploader = new qiniu.form_up.FormUploader(config); | |
console.log(" - upload: ", fileName); | |
formUploader.put(uploadToken, key, data, putExtra, | |
function (respErr, respBody, respInfo) { | |
if (respErr) { | |
console.log(respErr); | |
reject(respErr); | |
} | |
if (respInfo.statusCode === 200) { | |
bucketManager.changeMime(config.qiniu_bucket, key, getMimeType(fileName), function (err, _respBody, respInfo) { | |
if (err) { | |
console.log(err); | |
reject(err); | |
} else { | |
if (respInfo.statusCode === 200) { | |
resolve(respBody); | |
} else { | |
console.log([respInfo.statusCode, _respBody]); | |
reject([respInfo.statusCode, _respBody]); | |
} | |
} | |
}); | |
} else { | |
console.log([respInfo.statusCode, respBody]); | |
reject([respInfo.statusCode, respBody]); | |
} | |
}); | |
}); | |
}) | |
} | |
function checksum(str, algorithm, encoding) { | |
return crypto | |
.createHash(algorithm || 'md5') | |
.update(str, 'utf8') | |
.digest(encoding || 'hex') | |
} | |
const fileOptions = { encoding: "utf8" }; | |
let indexContents = fs.readFileSync(INDEX_FILE_NAME, fileOptions); | |
async function prod(regexp, minificationType) { | |
let match = regexp.exec(indexContents); | |
let results = []; | |
let replacements = []; | |
while (match != null) { | |
let matchedText = match[0]; | |
let before = match[1]; | |
let fname = match[2]; | |
let after = match[3]; | |
if (fname.indexOf('?') >= 0) { | |
fname = fname.substring(0, fname.indexOf('?')) | |
} | |
results.push( | |
await upload(fname, minificationType).then(_ => { | |
let url = config.qiniu_domain + '/' + _.key; | |
console.log(" - - done " + url); | |
replacements.push([matchedText, before + url + after]); | |
}) | |
); | |
match = regexp.exec(indexContents); | |
} | |
replacements.forEach(replacement => { | |
indexContents = indexContents.replace(replacement[0], replacement[1]); | |
}); | |
return results; | |
} | |
(async () => { | |
await prod(/(<script .*?src\s*=\s*['"]\s*)(.+?)(\s*['"].*?>)/img, 'js'); | |
await prod(/(<link .*?href\s*=\s*['"]\s*)(.+?)(\s*['"].*?>)/img, 'css'); | |
fs.writeFileSync(INDEX_FILE_NAME, indexContents, fileOptions); | |
console.log("\n\nwriting to ",INDEX_FILE_NAME); | |
console.log("done"); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment