2017-10-02 4 views
0

Tout d'abord, désolé mon anglais.Uglify plusieurs .js à différents dossiers (mais avec la même portée)

Je développe le frontend d'un système où j'ai des fichiers js qui seront concaténés et améliorés pour app.js. C'est bon. Mais, certains fichiers js seront chargés à la demande, c'est-à-dire que les fichiers seront dans différents dossiers, chargés par requête, et consommeront l'application app.js. Mon problème est que j'ai besoin d'uglify les variables globales et les fonctions de noms, et quand je vais grossir mes scripts, les fichiers ne contiennent pas le "contexte" égal.

Mon struct:

|project 
    |scripts 
    |core 
     *.js 
    |utils 
     *.js 
    |pages 
     *.js 
    app.js 
    vendor.js 
    |templates 
    *.hbs // this files will be "compiled" to js with gulp-handlebars 

Mon résultat de construction:

|public 
    |assets 
    |js 
     |pages // separated files, uglified with app.js scope 
     *.js 
     |templates // separated files, uglified with app.js scope 
     *.js 
     app.js // concat and uglify app.js, core and utils directories 
     vendor.js // uglify separed keeping global variables (bower) 

Pour faciliter l'explication, considérer que public/assets/js/app.js ont une fonction translate(a). Cela reçoit juste la variable 'a' et renvoie la valeur. Ex:

function translate(a) { 
    return a; 
} 

Tout d'abord, le fichier app.js est le seul chargé dans mon html. En fonction des paramètres régionaux du site, les fichiers des pages et les répertoires des modèles seront chargés dynamiquement dans le fichier html, en consommant les fonctions app.js.

Ex: public/assets/js/pages/*.js ou public/assets/js/templates/*.js:

function consumeApp(a) { 
    return translate(a); 
} 

Mon problème est que la fonction « translate » n'est pas défini pour les fichiers js dans les pages et les répertoires de modèle, car le enlaidir ne travaille pour différents fichiers besoin du même contexte/portée.

Mes dev dépendances (de package.json):

"devDependencies": { 
    "babel-core": "^6.4.0", 
    "babel-preset-es2015": "^6.3.13", 
    "babel-register": "^6.5.2", 
    "bower": "^1.8.0", 
    "del": "^1.1.1", 
    "gulp": "^3.9.1", 
    "gulp-autoprefixer": "^3.1.1", 
    "gulp-babel": "^6.1.1", 
    "gulp-bower": "0.0.13", 
    "gulp-browserify": "^0.5.1", 
    "gulp-cache": "^0.4.6", 
    "gulp-concat": "^2.6.1", 
    "gulp-cssnano": "^2.1.2", 
    "gulp-declare": "^0.3.0", 
    "gulp-eslint": "^3.0.1", 
    "gulp-handlebars": "^4.0.0", 
    "gulp-htmlmin": "^3.0.0", 
    "gulp-imagemin": "^3.2.0", 
    "gulp-include": "^2.3.1", 
    "gulp-load-plugins": "^1.5.0", 
    "gulp-plumber": "^1.1.0", 
    "gulp-precompile-handlebars": "^2.0.5", 
    "gulp-sass": "^3.1.0", 
    "gulp-size": "^2.1.0", 
    "gulp-sourcemaps": "^2.6.0", 
    "gulp-sync": "^0.1.4", 
    "gulp-uglify": "^2.1.2", 
    "gulp-wrap": "^0.13.0", 
    "handlebars": "^4.0.10", 
    "jscs": "^3.0.7", 
    "uniq": "^1.0.1", 
    "webpack": "^2.6.1", 
    "webpack-stream": "^3.2.0" 
    } 

Mon gulpfile (seulement enlaidir section):

const gulp = require('gulp'); 
const gulpsync = require('gulp-sync')(gulp); 
const gulpLoadPlugins = require('gulp-load-plugins'); 
const del = require('del'); 
const concat = require('gulp-concat'); 
const webpack = require('webpack-stream'); 

const $ = gulpLoadPlugins(); 

// .... uglify tasks run after all be in public 

gulp.task('scripts:uglify', gulpsync.sync([ 
    'scripts:uglify-vendor', 
    'scripts:uglify-app' 
])); 

gulp.task('scripts:uglify-app',() => { 
    return gulp.src([ 
     'public/assets/js/**/*js', 
     '!public/assets/js/vendor.js', 
    ]).pipe($.uglify({ 
     mangle: { 
      toplevel: true 
     } 
    })) 
     .pipe(gulp.dest('public/assets/js')); 
}); 

gulp.task('scripts:uglify-vendor',() => { 
    return gulp.src('public/assets/js/vendor.js') 
     .pipe($.uglify({mangle: false})) 
     .pipe(gulp.dest('public/assets/js')); 
}); 

Quelqu'un sait pourquoi? Merci.

+0

Qu'est-ce qui se passe si vous changez essoreuse: { toplevel: true} juste mutiler: faux? – Mark

+0

Si mangle est faux, mes variables globales et mes fonctions au niveau supérieur ne seront pas corrigées et seront accessibles à partir d'autres fichiers.Mais j'ai besoin d'uglify les variables globales et le nom et l'accès des fonctions d'un autre fichier avec le même contexte créé dans app.js uglified. –

+0

Fondamentalement, si translate() change en x() dans app.js, j'espère que tous les appels à translate() dans d'autres fichiers changent aussi en x(). –

Répondre

0

J'ai créé une méthode dans gulpfile, en utilisant node.js, qui "randomise" les variables globales et les fonctions spécifiques pour résoudre mon problème. Pour ce faire, j'ai séparé toutes les variables globales dans un fichier unique appelé ./scripts/core/_variables.jsoù chaque variable est déclarée ligne pour la ligne. J'ai mappé toutes les variables globales dinamiquement, en concaténant avec le nom de fonctions et je remplace dans les fichiers déjà construits en ./public/assets/js/**/*.js. L'algorithme ci-dessous peut être configuré avec des noms de fonctions et des répertoires aléatoires.

const fs = require('fs'); // added 
const prettyjson = require('prettyjson'); // added 

const consoleLog = (msg) => { 
    console.log(prettyjson.render(msg)); 
}; 

gulp.task('run-build', gulpsync.sync([ 
    'myTasks', // tasks to run build 
]]),() => { 
    return gulp.src('public/assets/**/*').pipe($.size({title: 'build', gzip: true})); 
}); 

gulp.task('build', gulpsync.sync(['run-build', 'randomly']),() => { 
    return true; 
}); 

gulp.task('randomly',() => { 
    return new Promise(function(resolve) { 

     // set here the functions name to randomly 
     function getFunctions() { 
      consoleLog('get functions name'); 
      return [ 
       'translate', 
       'myFirstFunction', 
       'mySecondFunction' 
      ] 
     } 

     // get automatically variables in ./scripts/core/_variables.js 
     function getVariables() { 
      consoleLog('start global variables loader'); 

      var fileContent = fs.readFileSync('./scripts/core/_variables.js', 'utf8'); 
      var a = fileContent.split('='); 
      var consts = [], 
       lets = []; 
      for (var i = 0; i < a.length; i++) { 
       var c = a[i].split('const '), 
        l = a[i].split('let '); 
       if (c[1]) 
        consts.push(c[1].toString().trim()); 
       if (l[1]) 
        lets.push(l[1].toString().trim()); 
      } 
      consoleLog('finished global variables loader'); 
      return consts.concat(lets); 
     } 

     // set random unique names to variables and functions 
     function setRandomNames(variables) { 
      return new Promise(function(resolve) { 
       consoleLog('start fake names generator'); 
       var fakeNames = []; 
       var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; 

       function existFakeName(name) { 
        for(var i in fakeNames) 
         if(fakeNames[i].fake === name) 
          return true; 
        return false; 
       } 

       function newNames() { 
        return new Promise(function(resolve) { 
         var name = ''; 
         for (var i = 0; i < 10; i++) 
          name += possible.charAt(Math.floor(Math.random() * possible.length)); 
         if (fakeNames.length <= variables.length && !existFakeName(name)) { 
          var item = fakeNames.length; 
          fakeNames.push({ 
           name: variables[item], 
           fake: name 
          }); 
          if (fakeNames.length === variables.length) { 
           consoleLog(fakeNames); 
           consoleLog('finished fake names generator'); 
           resolve(); 
          } 
          else 
           resolve(newNames()); 
         } 
         else 
          resolve(newNames()); 
        }); 
       } 
       newNames().then(() => { 
        resolve(fakeNames); 
       }) 
      }); 
     } 

     function listDirectory(dir) { 
      return new Promise((resolve) => { 
       var listFiles = fs.readdirSync(dir); 
       var response = []; 
       for (var i in listFiles) { 
        response.push(dir + listFiles[i]); 
       } 
       resolve(response); 
      }); 
     } 
     function replaceFile(file, fakes) { 
      return new Promise(function(resolve) { 
       // consoleLog('start replace file ' + file); 

       var fileContent = fs.readFileSync(file, 'utf8'); 
       for (var i in fakes) 
        fileContent = fileContent.split(fakes[i].name).join(fakes[i].fake); 
       resolve(writeFile(file, fileContent)); 
      }) 
     } 
     function writeFile(file, fileContent) { 
      return new Promise(function(resolve) { 
       fs.writeFile(file, fileContent, function (err) { 
        if (err) { 
         consoleLog('error ' + file); 
         resolve(); 
        } 

        // consoleLog('finished replace file and saved: ' + file); 
        resolve(); 
       }); 
      }); 
     } 

     consoleLog('start randomly'); 
     setRandomNames(getVariables().concat(getFunctions())).then(function(fakes) { 
      consoleLog('start list directories'); 
      Promise.all([ 
       listDirectory('./public/assets/js/pages/') 
      ]).then(function(response) { 

       consoleLog('finished list directories'); 

       var files = ['./public/assets/js/app.js']; // change app.js 
       for (var i in response) 
        files = files.concat(response[i]); 

       var promises = []; 
       for(var file in files) 
        promises.push(replaceFile(files[file], fakes)); 

       Promise.all(promises).then(function() { 
        consoleLog('all files replaced and saved'); 
        consoleLog('finished randomly'); 
        resolve(); 
        return true; 
       }); 
      }); 
     }); 
    }); 
});