開発環境でデバッグする際にconsole.log()をよく使いますけど、本番環境ではあまり使わないので、ここでconsole.log()を例として、webpackのloaderで無用なコードをignoreする方法を説明させて頂きます。
そもそもwebpackのloaderはfunctionなので、正規表現とreplace()メソッドで無用なコードを空文字列で交換するfunctionを実装します: ネストされた括弧を扱うのはjavascriptの正規表現の処理能力を超えいるため、ここで、再帰関数で実装します:
loaders/ignoreUnuseCode.js
function ignoreUnuseConsoleLog(code) {
const indexStart = code.indexOf("console.log(")
if (indexStart === -1) return code
let i = indexStart + "console.log(".length - 1
let leftParenthesisNeedToBeMatched = 1
for (i < code.length ; i++;) {
if (code[i] === "(") {
leftParenthesisNeedToBeMatched +=1
}
if (code[i] === ")") {
leftParenthesisNeedToBeMatched -=1
const next = i + 1
if (code[next] === ";") i++
}
if (leftParenthesisNeedToBeMatched === 0) break
}
const unuseConsoleLog = code.slice(indexStart, i+1)
code = code.replace(unuseConsoleLog, "")
return ignoreUnuseConsoleLog(code)
}
module.exports = ignoreUnuseConsoleLog
or
再帰使用しない:
loaders/ignoreUnuseCode.js
function ignoreUnuseConsoleLog(code) {
const indexes = [...code.matchAll(/console\.log\(/g)]
const resultArr = []
let left = indexes[0]
let remain = 1
for (let i = 0; i < code.length; i++) {
const char = code[i]
if (left) {
if (i < left.index)
resultArr.push(char)
else if (i >= left.index + 12) {
if (char === '(')
remain += 1
else if (char === ')')
remain -= 1
if (remain === 0) {
remain = 1
while (left = indexes.shift()) {
if (left.index > i)
break
}
}
}
} else
resultArr.push(char)
}
return resultArr.join('')
}
module.exports = ignoreUnuseConsoleLog
本番環境のwebpack configファイルにignoreUnuseCodeのloaderを追加します、resolveLoaderでloadersフォルダを指定することを忘れないように:
webpack.prod.conf.js
var path = require('path')
module.exports = {
/*他のオプション...*/
module: {
rules: [
{
test: /\.js$/,
use: ['ignoreUnuseCode'],
},
]
},
resolveLoader: {
modules: ['node_modules', path.resolve(__dirname, 'loaders')]
}
}
demo.js
document.write('<h1>Hello World</h1>');
console.log("debug something");alert("alert something");console.log("debug something");
function debug(a) {
return a
}
console.log(debug())