js-encode-plugin.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // 1、js-encode-plugin.js 文件(webpack的js加密插件)
  2. const fs = require('fs');//node的文件系统模块,用于读写及操作文件
  3. const path = require('path');//node提供的一些用于处理文件路径的小工具
  4. var chalk = require('chalk')//用于向控制台输出带颜色的问题提示
  5. // 2、模块对外暴露的 js 函数
  6. function JsEncodePlugin(pluginOptions) {
  7. this.options = pluginOptions;
  8. }
  9. // 3、原型定义一个 apply 函数,并注入了 compiler 对象
  10. JsEncodePlugin.prototype.apply = function (compiler) {
  11. const _this = this;
  12. // 4、挂载 webpack 事件钩子(这里挂载的是 after-emit 事件,在将内存中 assets 内容写到磁盘文件夹之后触发的webpack生命周期钩子)
  13. compiler.plugin('after-emit', function (compilation, callback) {
  14. // ... 内部进行自定义的编译操作
  15. // 5、操作 compilation 对象的内部数据
  16. console.log(chalk.cyan('\n jsencode start.\n'))
  17. var filePath = path.resolve(__dirname, _this.options.assetsPath);//设置需要加密的js文件路径,_this.options.assetsPath为插件配置中传过来的需要加密的js文件路径
  18. filterFile(filePath);
  19. function filterFile(fp){
  20. fs.readdir(fp, (err, files)=>{//读取该文件路径
  21. if(err){
  22. console.log(chalk.yellow(
  23. '读取js文件夹异常:\n' +
  24. err.message + '\n'
  25. ))
  26. return;
  27. }
  28. files.forEach((filename)=>{//遍历该路径下所有文件
  29. if(_this.options.jsReg.test(filename)){//利用正则匹配我们要加密的文件,_this.options.jsReg为插件中传过来的需要加密的js文件正则,用以筛选出我们需要加密的js文件。
  30. var filedir = path.resolve(fp, filename);
  31. fs.readFile(filedir, 'utf-8', (err, data)=>{//读取文件源码
  32. if(err){
  33. console.log(chalk.yellow(
  34. '读取js文件异常:\n' +
  35. err.message + '\n'
  36. ))
  37. return;
  38. }
  39. //调用jjencode函数对源码进行jjencode加密,_this.options.global为插件配置中传过来的加密使用的全局变量名,将在jjencode函数中作为第一个参数传入
  40. let result = jjencode(_this.options.global, data);
  41. fs.writeFile(filedir, result, (err)=>{//将加密后的代码写回文件中
  42. if(err){
  43. console.log(chalk.yellow(
  44. '写入加密后的js文件异常:\n' +
  45. err.message + '\n'
  46. ))
  47. return;
  48. }
  49. console.log(chalk.cyan(' jsencode complete.\n'))
  50. })
  51. })
  52. }
  53. })
  54. })
  55. }
  56. //js加密函数
  57. function jjencode( gv, text )
  58. {
  59. var r="";
  60. var n;
  61. var t;
  62. var b=[ "___", "__$", "_$_", "_$$", "$__", "$_$", "$$_", "$$$", "$___", "$__$", "$_$_", "$_$$", "$$__", "$$_$", "$$$_", "$$$$", ];
  63. var s = "";
  64. for( var i = 0; i < text.length; i++ ){
  65. n = text.charCodeAt( i );
  66. if( n == 0x22 || n == 0x5c ){
  67. s += "\\\\\\" + text.charAt( i ).toString(16);
  68. }else if( (0x20 <= n && n <= 0x2f) || (0x3A <= n == 0x40) || ( 0x5b <= n && n <= 0x60 ) || ( 0x7b <= n && n <= 0x7f ) ){
  69. s += text.charAt( i );
  70. }else if( (0x30 <= n && n <= 0x39 ) || (0x61 <= n && n <= 0x66 ) ){
  71. if( s ) r += "\"" + s +"\"+";
  72. r += gv + "." + b[ n < 0x40 ? n - 0x30 : n - 0x57 ] + "+";
  73. s="";
  74. }else if( n == 0x6c ){ // 'l'
  75. if( s ) r += "\"" + s + "\"+";
  76. r += "(![]+\"\")[" + gv + "._$_]+";
  77. s = "";
  78. }else if( n == 0x6f ){ // 'o'
  79. if( s ) r += "\"" + s + "\"+";
  80. r += gv + "._$+";
  81. s = "";
  82. }else if( n == 0x74 ){ // 'u'
  83. if( s ) r += "\"" + s + "\"+";
  84. r += gv + ".__+";
  85. s = "";
  86. }else if( n == 0x75 ){ // 'u'
  87. if( s ) r += "\"" + s + "\"+";
  88. r += gv + "._+";
  89. s = "";
  90. }else if( n < 128 ){
  91. if( s ) r += "\"" + s;
  92. else r += "\"";
  93. r += "\\\\\"+" + n.toString( 8 ).replace( /[0-7]/g, function(c){ return gv + "."+b[ c ]+"+" } );
  94. s = "";
  95. }else{
  96. if( s ) r += "\"" + s;
  97. else r += "\"";
  98. r += "\\\\\"+" + gv + "._+" + n.toString(16).replace( /[0-9a-f]/gi, function(c){ return gv + "."+b[parseInt(c,16)]+"+"} );
  99. s = "";
  100. }
  101. }
  102. if( s ) r += "\"" + s + "\"+";
  103. r =
  104. gv + "=~[];" +
  105. gv + "={___:++" + gv +",$$$$:(![]+\"\")["+gv+"],__$:++"+gv+",$_$_:(![]+\"\")["+gv+"],_$_:++"+
  106. gv+",$_$$:({}+\"\")["+gv+"],$$_$:("+gv+"["+gv+"]+\"\")["+gv+"],_$$:++"+gv+",$$$_:(!\"\"+\"\")["+
  107. gv+"],$__:++"+gv+",$_$:++"+gv+",$$__:({}+\"\")["+gv+"],$$_:++"+gv+",$$$:++"+gv+",$___:++"+gv+",$__$:++"+gv+"};"+
  108. gv+".$_="+
  109. "("+gv+".$_="+gv+"+\"\")["+gv+".$_$]+"+
  110. "("+gv+"._$="+gv+".$_["+gv+".__$])+"+
  111. "("+gv+".$$=("+gv+".$+\"\")["+gv+".__$])+"+
  112. "((!"+gv+")+\"\")["+gv+"._$$]+"+
  113. "("+gv+".__="+gv+".$_["+gv+".$$_])+"+
  114. "("+gv+".$=(!\"\"+\"\")["+gv+".__$])+"+
  115. "("+gv+"._=(!\"\"+\"\")["+gv+"._$_])+"+
  116. gv+".$_["+gv+".$_$]+"+
  117. gv+".__+"+
  118. gv+"._$+"+
  119. gv+".$;"+
  120. gv+".$$="+
  121. gv+".$+"+
  122. "(!\"\"+\"\")["+gv+"._$$]+"+
  123. gv+".__+"+
  124. gv+"._+"+
  125. gv+".$+"+
  126. gv+".$$;"+
  127. gv+".$=("+gv+".___)["+gv+".$_]["+gv+".$_];"+
  128. gv+".$("+gv+".$("+gv+".$$+\"\\\"\"+" + r + "\"\\\"\")())();";
  129. //console.log(r);
  130. return r;
  131. }
  132. // 6、执行 callback 回调
  133. callback();
  134. });
  135. };
  136. // 暴露 js 函数
  137. module.exports =JsEncodePlugin;