首先,对不起我的英语。
我正在开发一个系统的前端,我有一些js文件将被连接并升级到app.js.没关系。但是,一些js文件将按需加载,也就是说,文件将在不同的文件夹中,按请求加载,并使用uglified app.js。 我的问题是我需要uglify全局变量和名称函数,当我将uglify我的脚本时,文件不包含“上下文”相等。
我的结构:
|project
|scripts
|core
*.js
|utils
*.js
|pages
*.js
app.js
vendor.js
|templates
*.hbs // this files will be "compiled" to js with gulp-handlebars
我的构建结果:
|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)
为便于说明,请考虑public/assets/js/app.js
具有函数translate(a)
。这只是接收变量'a'并返回值。
例如:
function translate(a) {
return a;
}
首先,文件app.js是我的html中唯一加载的文件。根据站点的区域设置,页面和模板目录的文件将动态加载到html,消耗app.js函数。
例如:public/assets/js/pages/*.js
或public/assets/js/templates/*.js
:
function consumeApp(a) {
return translate(a);
}
我的问题是没有为页面和模板目录中的js文件定义函数“translate
”,因为uglify不适用于需要相同上下文/范围的不同文件。
我的开发依赖(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"
}
我的gulpfile(仅限uglify部分):
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'));
});
有人知道为什么吗? 感谢。
答案 0 :(得分:0)
我在gulpfile中使用node.js创建了一个方法,该方法“随机化”全局变量和特定函数来解决我的问题。为此,我将所有全局变量分隔在一个名为./scripts/core/_variables.js
的唯一文件中,其中每个变量都被声明为行。我以dinamically方式映射了所有全局变量,使用函数名称进行仲裁,然后在./public/assets/js/**/*.js
中已经构建的文件中替换。
下面的算法可以配置函数名称和目录,可以是randomfy。
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;
});
});
});
});
});