js对本地文件进行加密_webpack配置,对js文件进行加密

有的vue项目为提高安全系数,防止js文件敏感信息的泄露,会提出对dist中的js进行加密的需求。

解决方案:

1. 在build目录下新建js-encode-plugin.js文件(写一个JsEncodePlugin插件),内容如下;

// 1、js-encode-plugin.js 文件(webpack的js加密插件)const fs = require('fs');//node的文件系统模块,用于读写及操作文件const path = require('path');//node提供的一些用于处理文件路径的小工具var chalk = require('chalk')//用于向控制台输出带颜色的问题提示// 2、模块对外暴露的 js 函数function JsEncodePlugin(pluginOptions) {  this.options = pluginOptions;}// 3、原型定义一个 apply 函数,并注入了 compiler 对象JsEncodePlugin.prototype.apply = function (compiler) {  const _this = this;  // 4、挂载 webpack 事件钩子(这里挂载的是 after-emit 事件,在将内存中 assets 内容写到磁盘文件夹之后触发的webpack生命周期钩子)  compiler.plugin('after-emit', function (compilation, callback) {      // ... 内部进行自定义的编译操作      // 5、操作 compilation 对象的内部数据      console.log(chalk.cyan('\n jsencode start.\n'))      var filePath = path.resolve(__dirname, _this.options.assetsPath);//设置需要加密的js文件路径,_this.options.assetsPath为插件配置中传过来的需要加密的js文件路径      filterFile(filePath);      function filterFile(fp){        fs.readdir(fp, (err, files)=>{//读取该文件路径          if(err){            console.log(chalk.yellow(              '读取js文件夹异常:\n' +              err.message + '\n'            ))            return;          }          files.forEach((filename)=>{//遍历该路径下所有文件            if(_this.options.jsReg.test(filename)){//利用正则匹配我们要加密的文件,_this.options.jsReg为插件中传过来的需要加密的js文件正则,用以筛选出我们需要加密的js文件。              var filedir = path.resolve(fp, filename);              fs.readFile(filedir, 'utf-8', (err, data)=>{//读取文件源码                if(err){                  console.log(chalk.yellow(                    '读取js文件异常:\n' +                    err.message + '\n'                  ))                  return;                }        //调用jjencode函数对源码进行jjencode加密,_this.options.global为插件配置中传过来的加密使用的全局变量名,将在jjencode函数中作为第一个参数传入                let result = jjencode(_this.options.global, data);                fs.writeFile(filedir, result, (err)=>{//将加密后的代码写回文件中                  if(err){                    console.log(chalk.yellow(                      '写入加密后的js文件异常:\n' +                      err.message + '\n'                    ))                    return;                  }                  console.log(chalk.cyan('  jsencode complete.\n'))                })              })            }          })        })      }      //js加密函数      function jjencode( gv, text )        {          var r="";          var n;          var t;          var b=[ "___", "__$", "_$_", "_$$", "$__", "$_$", "$$_", "$$$", "$___", "$__$", "$_$_", "$_$$", "$$__", "$$_$", "$$$_", "$$$$", ];          var s = "";          for( var i = 0; i < text.length; i++ ){            n = text.charCodeAt( i );            if( n == 0x22 || n == 0x5c ){                s += "\\\\\\" + text.charAt( i ).toString(16);            }else if( (0x20 <= n && n <= 0x2f) || (0x3A <= n == 0x40) || ( 0x5b <= n && n <= 0x60 ) || ( 0x7b <= n && n <= 0x7f ) ){                s += text.charAt( i );            }else if( (0x30 <= n && n <= 0x39 ) || (0x61 <= n && n <= 0x66 ) ){                if( s ) r += "\"" + s +"\"+";                r += gv + "." + b[ n < 0x40 ? n - 0x30 : n - 0x57 ] + "+";                s="";            }else if( n == 0x6c ){ // 'l'                if( s ) r += "\"" + s + "\"+";                r += "(![]+\"\")[" + gv + "._$_]+";                s = "";            }else if( n == 0x6f ){ // 'o'                if( s ) r += "\"" + s + "\"+";                r += gv + "._$+";                s = "";            }else if( n == 0x74 ){ // 'u'                if( s ) r += "\"" + s + "\"+";                r += gv + ".__+";                s = "";            }else if( n == 0x75 ){ // 'u'                if( s ) r += "\"" + s + "\"+";                r += gv + "._+";                s = "";            }else if( n < 128 ){                if( s ) r += "\"" + s;                else r += "\"";                r += "\\\\\"+" + n.toString( 8 ).replace( /[0-7]/g, function(c){ return gv + "."+b[ c ]+"+" } );                s = "";            }else{                if( s ) r += "\"" + s;                else r += "\"";                r += "\\\\\"+" + gv + "._+" + n.toString(16).replace( /[0-9a-f]/gi, function(c){ return gv + "."+b[parseInt(c,16)]+"+"} );                s = "";            }          }          if( s ) r += "\"" + s + "\"+";            r =             gv + "=~[];" +             gv + "={___:++" + gv +",$$$$:(![]+\"\")["+gv+"],__$:++"+gv+",$_$_:(![]+\"\")["+gv+"],_$_:++"+            gv+",$_$$:({}+\"\")["+gv+"],$$_$:("+gv+"["+gv+"]+\"\")["+gv+"],_$$:++"+gv+",$$$_:(!\"\"+\"\")["+            gv+"],$__:++"+gv+",$_$:++"+gv+",$$__:({}+\"\")["+gv+"],$$_:++"+gv+",$$$:++"+gv+",$___:++"+gv+",$__$:++"+gv+"};"+            gv+".$_="+            "("+gv+".$_="+gv+"+\"\")["+gv+".$_$]+"+            "("+gv+"._$="+gv+".$_["+gv+".__$])+"+            "("+gv+".$$=("+gv+".$+\"\")["+gv+".__$])+"+            "((!"+gv+")+\"\")["+gv+"._$$]+"+            "("+gv+".__="+gv+".$_["+gv+".$$_])+"+            "("+gv+".$=(!\"\"+\"\")["+gv+".__$])+"+            "("+gv+"._=(!\"\"+\"\")["+gv+"._$_])+"+            gv+".$_["+gv+".$_$]+"+            gv+".__+"+            gv+"._$+"+            gv+".$;"+            gv+".$$="+            gv+".$+"+            "(!\"\"+\"\")["+gv+"._$$]+"+            gv+".__+"+            gv+"._+"+            gv+".$+"+            gv+".$$;"+            gv+".$=("+gv+".___)["+gv+".$_]["+gv+".$_];"+            gv+".$("+gv+".$("+gv+".$$+\"\\\"\"+" + r + "\"\\\"\")())();";            //console.log(r);          return r;        }      // 6、执行 callback 回调      callback();    });  };  module.exports = JsEncodePlugin;

2. 在webpack的配置文件webpack.prod.conf.js中引入该插件

需要把plugins里的UglifyJsPlugin注释掉,因为UglifyJsPlugin插件的压缩和加密功能,JsEncodePllugin插件都能实现并且做得更好。

我这里只匹配app.js这个文件进行加密

513c2abcea5953487e9e962ddab03469.png

91fc0452a3498a82b6651a905cd3a2c3.png

再npm run build之后生成的app.js就不会泄露敏感信息了


版权声明:本文为weixin_33427476原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。