11"use strict" ;
22
3- import { Compiler } from 'webpack' ;
4-
5- const JavaScriptObfuscator = require ( 'javascript-obfuscator' ) ;
6- const RawSource = require ( "webpack-sources" ) . RawSource ;
7- const SourceMapSource = require ( "webpack-sources" ) . SourceMapSource ;
8- const multimatch = require ( 'multimatch' ) ;
3+ import { Compiler , compilation } from 'webpack' ;
4+ import JavaScriptObfuscator from 'javascript-obfuscator' ;
5+ import { RawSource , SourceMapSource } from 'webpack-sources' ;
6+ import multimatch from 'multimatch' ;
7+ import { RawSourceMap } from 'source-map' ;
8+ import { TInputOptions as JavascriptObfuscatorOptions } from 'javascript-obfuscator/src/types/options/TInputOptions' ;
99const transferSourceMap = require ( "multi-stage-sourcemap" ) . transfer ;
1010
11- type TObject = { [ key : string ] : any } ;
12-
1311class WebpackObfuscator {
14- /**
15- * @type {TObject }
16- */
17- public options : TObject = { } ;
1812
19- /**
20- * @type {string }
21- */
22- public excludes : string [ ] ;
13+ public excludes : string [ ] = [ ] ;
2314
24- /**
25- * @param {TObject } options
26- * @param {string | string[] } excludes
27- */
28- constructor ( options : TObject , excludes : string | string [ ] ) {
29- this . options = options || { } ;
30- this . excludes = this . prepareExcludes ( excludes ) ;
15+ constructor (
16+ public options : JavascriptObfuscatorOptions ,
17+ excludes ?: string | string [ ]
18+ ) {
19+ this . excludes = this . excludes . concat ( excludes || [ ] ) ;
3120 }
3221
33- /**
34- * @param {Compiler } compiler
35- */
36- public apply ( compiler : Compiler ) : void {
37- compiler . plugin ( 'compilation' , ( compilation : any ) => {
38- compilation . plugin ( "optimize-chunk-assets" , ( chunks : any [ ] , callback : ( ) => void ) => {
39- let files = [ ] ;
40-
41- chunks . forEach ( ( chunk ) => {
42- chunk [ 'files' ] . forEach ( ( file ) => {
43- files . push ( file ) ;
22+ public apply ( compiler : Compiler ) : void {
23+ const isDevServer = process . argv . find ( v => v . includes ( 'webpack-dev-server' ) ) ;
24+ if ( isDevServer ) {
25+ console . info (
26+ 'JavascriptObfuscator is disabled on webpack-dev-server as the reloading scripts ' ,
27+ 'and the obfuscator can interfere with each other and break the build' ) ;
28+ return ;
29+ }
30+
31+ const pluginName = this . constructor . name ;
32+ compiler . hooks . emit . tap ( pluginName , ( compilation : compilation . Compilation ) => {
33+ for ( const fileName in compilation . assets ) {
34+ if ( ! fileName . toLowerCase ( ) . endsWith ( '.js' ) || this . shouldExclude ( fileName ) ) {
35+ return ;
36+ }
37+ const asset = compilation . assets [ fileName ]
38+ const { inputSource, inputSourceMap } = this . extractSourceAndSourceMap ( asset ) ;
39+ const { obfuscatedSource, obfuscationSourceMap } = this . obfuscate ( inputSource ) ;
40+
41+ if ( this . options . sourceMap && inputSourceMap ) {
42+ const transferredSourceMap = transferSourceMap ( {
43+ fromSourceMap : obfuscationSourceMap ,
44+ toSourceMap : inputSource
4445 } ) ;
45- } ) ;
46-
47- compilation . additionalChunkAssets . forEach ( ( file ) => {
48- files . push ( file ) ;
49- } ) ;
50-
51- files . forEach ( ( file ) => {
52- if ( ! / \. j s ( $ | \? ) / i. test ( file ) || this . shouldExclude ( file , this . excludes ) ) {
53- return ;
54- }
55-
56- let asset = compilation . assets [ file ] ,
57- input , inputSourceMap ;
58-
59- if ( this . options . sourceMap !== false ) {
60- if ( asset . sourceAndMap ) {
61- let sourceAndMap = asset . sourceAndMap ( ) ;
62- inputSourceMap = sourceAndMap . map ;
63- input = sourceAndMap . source ;
64- } else {
65- inputSourceMap = asset . map ( ) ;
66- input = asset . source ( ) ;
67- }
68-
69- if ( inputSourceMap ) {
70- this . options . sourceMap = true ;
71- }
72- } else {
73- input = asset . source ( ) ;
74- }
7546
76- let obfuscationResult : any = JavaScriptObfuscator . obfuscate (
77- input ,
78- this . options
47+ compilation . assets [ fileName ] = new SourceMapSource (
48+ obfuscatedSource ,
49+ fileName ,
50+ transferredSourceMap ,
51+ inputSource ,
52+ inputSourceMap
7953 ) ;
80-
81- if ( this . options . sourceMap ) {
82- let obfuscationSourceMap : any = obfuscationResult . getSourceMap ( ) ,
83- transferredSourceMap : any = transferSourceMap ( {
84- fromSourceMap : obfuscationSourceMap ,
85- toSourceMap : inputSourceMap
86- } ) ;
87-
88- compilation . assets [ file ] = new SourceMapSource (
89- obfuscationResult . toString ( ) ,
90- file ,
91- JSON . parse ( transferredSourceMap ) ,
92- asset . source ( ) ,
93- inputSourceMap
94- ) ;
95- } else {
96- compilation . assets [ file ] = new RawSource ( obfuscationResult . toString ( ) ) ;
97- }
98- } ) ;
99-
100- callback ( ) ;
101- } ) ;
54+ } else {
55+ compilation . assets [ fileName ] = new RawSource ( obfuscatedSource ) ;
56+ }
57+ }
10258 } ) ;
10359 }
10460
105- private prepareExcludes ( inputExcludes : string | string [ ] ) : string [ ] {
106- if ( Array . isArray ( inputExcludes ) ) {
107- return inputExcludes ;
108- }
61+ private shouldExclude ( filePath : string ) : boolean {
62+ return multimatch ( filePath , this . excludes ) . length > 0
63+ }
10964
110- if ( typeof inputExcludes === 'string' ) {
111- return [ inputExcludes ] ;
65+ private extractSourceAndSourceMap ( asset : any ) : { inputSource : string , inputSourceMap : RawSourceMap } {
66+ if ( asset . sourceAndMap ) {
67+ const { source, map } = asset . sourceAndMap ( ) ;
68+ return { inputSource : source , inputSourceMap : map } ;
69+ } else {
70+ return {
71+ inputSource : asset . source ( ) ,
72+ inputSourceMap : asset . map ( )
73+ }
11274 }
113-
114- return [ ] ;
11575 }
11676
117- /**
118- * @param filePath
119- * @param excludes
120- * @returns {boolean }
121- */
122- private shouldExclude ( filePath : string , excludes : string [ ] ) : boolean {
123- return multimatch ( filePath , excludes ) . length > 0
77+ private obfuscate ( javascript : string ) : { obfuscatedSource : string , obfuscationSourceMap : string } {
78+ const obfuscationResult = JavaScriptObfuscator . obfuscate (
79+ javascript ,
80+ this . options
81+ ) ;
82+
83+ return {
84+ obfuscatedSource : obfuscationResult . getObfuscatedCode ( ) ,
85+ obfuscationSourceMap : obfuscationResult . getSourceMap ( )
86+ }
12487 }
12588}
12689
127- module . exports = WebpackObfuscator ;
90+ export = WebpackObfuscator ;
0 commit comments