前端專案程式碼加密教程

不該相遇在秋天發表於2019-06-24

  我們都知道,瀏覽器上是可以看到前端的html和js程式碼的,所以如果遇到隱私心比較強的老闆,你就冷不丁的會接受到一個程式碼加密的需求,當接受到這個需求的時候你怎麼完成?那我希望我的這篇部落格可以幫助到你。

  首先,告訴你的老闆,嚴格意義上的加密是不存在的,能夠實現的只有對前端程式碼進行壓縮混淆,增加閱讀難度。

  本篇教程全篇描述的,就是對程式碼進行混淆的手段,從而滿足老闆提出的加密需求。

  為了保證本篇教程真實可用,我將使用一臺新的Windows系統,從無到有進行演示,同時將操作流程記錄在這裡,供你參考,也希望能夠幫你跳過一些坑,如果你遇到什麼問題,請留言討論。

 

安裝NodeJs

  如果你沒安裝過node,請跟著教程走,如果你安裝過,請直接跳到下一節。

  下載地址:http://nodejs.cn/download/

 

  直接下載安裝,安裝的過程是傻瓜式的下一步,唯一可以改變的是安裝位置。

 

  安裝完成後開啟cmd命令列,檢視版本號是為了確認是否安裝成功。

  

 

安裝外掛

  切換到專案根目錄:

  

 

  安裝gulp外掛包:npm install --save-dev gulp

  效果如圖:

  

 

  別急,還有很多包,命令一條一條刷起來:

 

  npm install --save-dev del

  npm install --save-dev gulp-concat

  npm install --save-dev gulp-header

  npm install --save-dev gulp-if

  npm install --save-dev gulp-minify-css

  npm install --save-dev gulp-htmlmin

  npm install --save-dev gulp-rename

  npm install --save-dev gulp-replace

  npm install --save-dev gulp-uglify

  npm install --save-dev gulp-babel

  npm install --save-dev babel-preset-es2015

  npm install --save-dev @babel/core

  npm install --save-dev @babel/preset-env

 

注意事項

  外掛安裝完成後,我們的前期工作就做完了。

  我們會發現專案目錄中多個一個node_modules目錄和package-lock.json檔案,json檔案中是我們的外掛列表,node_modules目錄中是我們安裝的外掛包。

  

  index.html是我的主入口檔案,src目錄就是我的專案中存放程式碼的目錄,也就是我要壓縮加密構建的目錄。

 

  

  src裡有三個子目錄,controller存放獨立的js處理前端業務邏輯,style存放css樣式檔案,view存放html頁面。

 

  在編寫指令碼之前,我需要直白的告訴你,如果你的JS裡有ES6語法,正常打包是打不了的,不過我們的前期工作已經把處理這個問題的工具包也一起安裝了,但是也僅限於處理單獨的JS檔案。

  如果你是HTML程式碼裡嵌JS,並且JS裡有ES6語法,那麼需要把JS程式碼拎出來做成單獨的JS,或者手動將ES6寫法改成ES5。

 

  總之,如果你打包報錯,很大可能是ES6語法導致,其次是檔案路徑錯誤。

 

壓縮JS

  回到我們的專案根目錄,建立一個gulpfile.js檔案,這個是固定的檔名:

  

引入包:

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var babel = require('gulp-babel');
var minifyCss = require("gulp-minify-css");
var htmlmin = require('gulp-htmlmin');
var header = require('gulp-header');
var del = require('del');

 

定義一個目標目錄:

var destDir = './dist';

 

定義一個註釋,因為我希望在壓縮後的程式碼中第一行新增一點註釋:

var note = ['/**  小樣,看原始碼?想得美! */\n <%= js %>', {js: ';'}];

 

監聽任務:

gulp.task('minjs', function () {
    //定義路徑
    var src = [
        './src/**/*.js'
    ];
    gulp.src(src)
        .pipe(babel({presets: ["@babel/env"], plugins: []}))//es6轉es5
        .pipe(uglify())//壓縮
        .pipe(header.apply(null, note))//新增頭部註釋
        .pipe(gulp.dest(destDir));//將壓縮後的內容輸出到目標目錄
});

  minjs就是我們自定義的任務名,也就是說 我們在命令列輸入gulp minjs 這行命令,這段程式碼就會執行。

  如果只輸入gulp命令,它會自動去找名為default的任務。

 

  var src = ['./src/**/*.js']; 就是我們想要抓取的檔案,使用了萬用字元,你幾乎一定會有需求像下面這樣寫:

var src = [
        './src/**/*.js'
        , '!./src/config.js'
        , '!./src/lib/extend/*.js'
    ];

  感嘆號的意思是排除。

 

  這裡說明一下destDir只會代替萬用字元之前的目錄路徑,比如說我這裡的destDir定義的是./dist,那麼 ./src/controller/admin.js 壓縮後的路徑就是 ./dist/controller/admin.js。

 

  好了,開啟命令列,輸入命令:gulp minjs

  

 

 

  檢視專案,js檔案已經壓縮成功了。

 

壓縮CSS

  任務的監聽和壓縮JS是沒有差別的,只不過壓縮任務用gulp-minify-css外掛來完成。

gulp.task('mincss', function () {
    var src = [
        './src/style/*.css'
    ];
    gulp.src(src).pipe(minifyCss()).pipe(gulp.dest(destDir + '/style'));
});

 

  輸入命令:gulp mincss

  

 

  檢視專案也沒有任何問題:

  非常智慧的它會把css中的註釋給你刪掉。

 

壓縮HTML

  壓縮HTML可以傳入很多引數指定相應的行為:

gulp.task('minhtml', function () {
    var options = {
        removeComments: true,//清除HTML註釋
        collapseWhitespace: true,//摺疊空白
        minifyJS: true,//壓縮頁面JS
        minifyCSS: true//壓縮頁面CSS
    };
    var src = [
        './src/views/**/*',
    ];
    gulp.src(src)
        .pipe(htmlmin(options))
        .pipe(gulp.dest(destDir + '/views'));
});

  更多引數請移步這裡來看:https://github.com/kangax/html-minifier/blob/gh-pages/README.md

 

  輸入命令:gulp minhtml

  

 

 

  壓縮後的HTML:

 

  全部壓成一行,檔案中的css和js也一併壓縮了。

 

一條龍處理

  但是我們總不可能是打個包要跑多條命令吧,那多麻煩,現在我們就整合整合,讓這些任務合併成一個任務。

  我們建立一個task物件,把各個任務的內容放進去,並且加一個清理dist目錄的方法,和一個move方法負責將沒有被壓縮的檔案複製過去。

//任務列表
var task = {
    //清理dist目錄
    clear:function () {
        del(['./dist/*']);
    },
    minjs:function () {
        //定義路徑
        var src = [
            './src/**/*.js'
        ];
        gulp.src(src)
            .pipe(babel({presets: ["@babel/env"], plugins: []}))//es6轉es5
            .pipe(uglify())//壓縮
            .pipe(header.apply(null, note))//新增頭部註釋
            .pipe(gulp.dest(destDir));
    },
    mincss:function () {
        var src = [
            './src/style/*.css'
        ];
        gulp.src(src).pipe(minifyCss()).pipe(gulp.dest(destDir + '/style'));
    },
    minhtml:function () {
        var options = {
            removeComments: true,//清除HTML註釋
            collapseWhitespace: true,//摺疊空白
            minifyJS: true,//壓縮頁面JS  如果你確信你的HTML頁面中的js不包含有es6語法,那麼可以壓縮js 否則還是得把js抽離成單獨的檔案進行壓縮
            minifyCSS: true//壓縮頁面CSS
        };
        var src = [
            './src/**/*',
        ];
        gulp.src(src)
            .pipe(htmlmin(options))
            .pipe(gulp.dest(destDir));
    },
    move: function () {
        //複製資料夾  沒有被壓縮的檔案就在這裡複製
        gulp.src('./src/**/*.png').pipe(gulp.dest(destDir));
    }
};

 

  我們在壓縮js的時候說了,如果只是gulp命令,它會去找名為default的任務,我們就在default任務裡遍歷task物件,將其中的方法輪流執行一遍。

gulp.task('default', function () {
    for (var key in task) {
        task[key]();
    }
});

  這樣,我們只需要一個gulp命令,也就走完了整個構建流程。

 

  同時,我們將單個的任務指向task中對應的方法:

gulp.task('clear',task.clear);
gulp.task('minjs',task.minjs);
gulp.task('mincss',task.mincss);
gulp.task('minhtml',task.minhtml);
gulp.task('move',task.move);

 

  無論是單獨處理一個環節,還是整個構建流程,我們都可以很方便的完成。

 

最後,感謝閱讀。  PS:歡迎關注,有粉必回。

 

相關文章