1
1
"use strict" ;
2
2
3
3
import JavaScriptObfuscator , { ObfuscatorOptions } from 'javascript-obfuscator' ;
4
- import estraverse from 'estraverse' ;
5
- import * as ESTree from 'estree' ;
6
4
import loaderUtils from 'loader-utils' ;
7
- import * as acorn from 'acorn' ;
8
-
9
- class WebpackObfuscatorLoaderHelper {
10
- /**
11
- * @type {acorn.Options['sourceType'][] }
12
- */
13
- private static readonly sourceTypes : acorn . Options [ 'sourceType' ] [ ] = [
14
- 'script' ,
15
- 'module'
16
- ] ;
17
-
18
- /**
19
- * @param {string } sourceCode
20
- * @returns {string }
21
- */
22
- public static getCommentedSource ( sourceCode : string ) : string {
23
- // Parses source code and collects require expression nodes
24
- const entries : {
25
- start : number ;
26
- end : number ;
27
- } [ ] = [ ] ;
28
- const astTree : ESTree . Program = WebpackObfuscatorLoaderHelper . parseCode ( sourceCode ) ;
29
-
30
- estraverse . traverse ( astTree , {
31
- enter : ( node : ESTree . Node ) : void => {
32
- if ( WebpackObfuscatorLoaderHelper . isRequire ( node ) && node . start && node . end ) {
33
- entries . push ( {
34
- start : node . start ,
35
- end : node . end ,
36
- } ) ;
37
- }
38
- }
39
- } ) ;
40
-
41
- // Wraps requires in conditional comments
42
- let commentedSource : string = sourceCode . slice ( ) ;
43
-
44
- entries
45
- . sort ( ( a , b ) => b . end - a . end )
46
- . forEach ( ( n ) => {
47
- const before = commentedSource . slice ( 0 , n . start ) ;
48
- const mid = commentedSource . slice ( n . start , n . end ) ;
49
- const after = commentedSource . slice ( n . end ) ;
50
-
51
- commentedSource = `${ before } /* javascript-obfuscator:disable */${ mid } /* javascript-obfuscator:enable */${ after } ` ;
52
- } ) ;
53
-
54
- return commentedSource ;
55
- }
56
-
57
- /**
58
- * @param {string } sourceCode
59
- * @returns {ESTree.Program }
60
- */
61
- private static parseCode ( sourceCode : string ) : ESTree . Program {
62
- const sourceTypeLength : number = WebpackObfuscatorLoaderHelper . sourceTypes . length ;
63
-
64
- for ( let i : number = 0 ; i < sourceTypeLength ; i ++ ) {
65
- try {
66
- return WebpackObfuscatorLoaderHelper . parseType ( sourceCode , WebpackObfuscatorLoaderHelper . sourceTypes [ i ] ) ;
67
- } catch ( error ) {
68
- if ( i < sourceTypeLength - 1 ) {
69
- continue ;
70
- }
71
-
72
- throw new Error ( error ) ;
73
- }
74
- }
75
-
76
- throw new Error ( 'Acorn parsing error' ) ;
77
- }
78
-
79
- /**
80
- * @param {string } sourceCode
81
- * @param {acorn.Options["sourceType"] } sourceType
82
- * @returns {Program }
83
- */
84
- private static parseType (
85
- sourceCode : string ,
86
- sourceType : acorn . Options [ 'sourceType' ]
87
- ) : ESTree . Program {
88
- const config : acorn . Options = {
89
- sourceType,
90
- ecmaVersion : 11
91
- } ;
92
-
93
- return < any > acorn . parse ( sourceCode , config ) ;
94
- }
95
-
96
- /**
97
- * @param {ESTree.Node } node
98
- * @returns {boolean }
99
- */
100
- private static isRequire ( node : ESTree . Node ) {
101
- return node . type === 'CallExpression'
102
- && node . callee . type === 'Identifier'
103
- && node . callee . name === 'require' ;
104
- }
105
- }
106
5
107
6
/**
108
7
* JavaScript Obfuscator loader based on `obfuscator-loader` package
@@ -111,8 +10,13 @@ function Loader (sourceCode: string) {
111
10
// Obfuscates commented source code
112
11
// @ts -ignore
113
12
const options = loaderUtils . getOptions < ObfuscatorOptions > ( this ) || { } ;
114
- const commentedSourceCode : string = WebpackObfuscatorLoaderHelper . getCommentedSource ( sourceCode ) ;
115
- const obfuscationResult = JavaScriptObfuscator . obfuscate ( commentedSourceCode , options ) ;
13
+ const obfuscationResult = JavaScriptObfuscator . obfuscate (
14
+ sourceCode ,
15
+ {
16
+ ...options ,
17
+ ignoreRequireImports : true
18
+ }
19
+ ) ;
116
20
117
21
return obfuscationResult . getObfuscatedCode ( ) ;
118
22
}
0 commit comments