到目前为止,我的项目中只有一个javascript文件,其中包含大量功能,其中只有少数功能被多个网页使用。随着涉及的代码量的增加,我可以看到文件变得混乱而且太长了。我正在考虑为每个网页提供一个单独的javascript文件,以便:
但我不知道这是否会产生任何我不知道的负面影响。
答案 0 :(得分:1)
较少的文件会导致代码不太干净,这反过来意味着编码速度变慢,难以调试。 更多文件意味着更多HTTP请求和更慢的网站。因此,要开发尽可能多的文件,以便组织代码并保持开发的可管理性。
答案 1 :(得分:1)
拥有多个文件确实可以帮助您整理好事情,但同时需要浏览器向服务器发出多个请求,这可能会影响网站加载时间。
这就是许多人现在使用RequireJS等工具的原因。
简而言之,它允许您根据需要定义任意数量的小模块(每个模块都在单独的文件中),然后它将异步加载它们。
如果你将它与一些构建工具(如Grunt)结合使用,你可以拥有一个只加载两个文件的网页(RequireJS库和你的JS文件,即main.js
),但是main.js
将是连接许多较小模块的结果。
通过这种方式,您可以将请求的数量保留在minium中,同时,您的代码将以小模块进行组织和拆分成本?您引入了一个额外的构建步骤。但是,使用grunt-contrib-watch
等工具可以进一步自动化此构建步骤。
以下是使用一个main.js
文件并依赖于将从Google CDN加载的jQuery的网站的几个代码段:
首先, main.js :这是一个RequireJS模块(它是一个AMD模块),看起来像:
// Tell RequireJS that jQuery dependency should be loaded from the given URL.
// Without this, RequireJS would try to find jQuery.js file locally.
requirejs.config({
paths: {
'jQuery': '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min',
},
shim: {
'jQuery': {'exports': 'jQuery'},
}
});
// You define that the module below depends on jQuery and two custom modules.
define(['jQuery', 'module1', 'module2'], function ($, Module1, Module2) {
// Here you can access $, Module1 and Module2
});
然后使用Grunt的grunt-contrib-requirejs
插件,配置类似于( Gruntfile.js ):
requirejs: {
compile: {
options: {
baseUrl: 'src/js', // modules dir, which contains main.js, module1.js etc.
out: 'static/js/main.js', // output file
name: 'main',
paths: {
'jQuery': 'http://lorem.ipsum1' // jQuery will be loaded separately from CDN
},
optimize: 'uglify2' // minify output file
}
}
}
最后,加载RequireJS脚本并告诉它使用main.js
文件作为您网站的入口点( index.html ):
<script src="js/require.min.js" data-main="js/main.js"></script>
答案 2 :(得分:1)
这里有很多选项,主要集中在组织文件方面,值得考虑使用像require.js 这样的库,如果你正在做的事情相当大。然而,这适用于应用程序,即使您可以轻松地将其用于其他事项,也就是您将代码重构为独立模块,这在您的案例中可能是合理的,也可能是不合理的。
然而,如果我们所讨论的javascript是紧密与页面内容相结合,因此在其设置中不能重复使用其他页面,使用内联{{1标签而不是外部javascript文件。
最后一个注意事项,require.js或任何带有多个javascript的设置会给http请求带来轻微的开销,但我不会太担心。 Require.js或类似的库甚至会为你加载这个异步,所以总而言之它可能比一个巨大的文件更有效,它可能不会用于任何给定访问者的大部分(尽管这取决于访问者是否最终会访问所有页面。)
答案 3 :(得分:0)
现在,我用一组逻辑文件夹(服务,控制器,Lib等)在分离的文件中开发我的所有javascript。
但是我在Node.js上使用Gulp和Bower。注意,我没有将Node.JS用作我的服务器端代码,只是我的前端资产。可以将其视为客户端资产的分发工具。我使用Gulp-Watch监视我的SRC文件夹,并在处理源代码时自动转换最终的javascript文件。
因此,我得到了将所有内容逻辑分离的好处,但仍然可以获得用于生产的单个压缩JS文件的性能。
以下是bower.json文件的示例:
{
"name": "MyApp",
"private": true,
"dependencies": {
"jquery": "2.2.4",
"bootstrap": "v4.0.0-alpha.3",
"angular": "^1.5.8",
"font-awesome": "fontawesome#^4.6.3",
"angular-ui-router": "^0.3.1",
"angular-cookies": "^1.5.8",
"angular-ui-select": "^0.19.4",
"angular-ui-tree": "^2.17.0",
"angular-toastr": "^2.0.0",
"angular-animate": "^1.5.8",
"angular-sanitize": "^1.5.8",
"angular-chart": "^0.5.0",
"angular-loading-bar": "^0.9.0",
"angular-messages": "^1.5.8"
},
"devDependencies": {}
}
这是Gulp-File
/// <binding Clean='clean' />
"use strict";
var gulp = require("gulp");
var sass = require("gulp-sass"); //Syntactically Awesome Style Sheets
var sourcemaps = require('gulp-sourcemaps'); //Generate source maps for css and js
var autoprefixer = require('gulp-autoprefixer'); //auto prefix browser specific css
var cleanCss = require('gulp-clean-css'); //minimize css
var rename = require('gulp-rename'); //rename file in gulp stream
var concat = require('gulp-concat'); //concat mutliple files in gulp stream into one
var runSequence = require('run-sequence'); //run mutliple gulp taxes in parrellel or sequence
var uglify = require('gulp-uglify'); //minimize js
var webroot = "./wwwroot/"; //the root folder where the css and js is going
var paths = {
css: webroot + "css/", //path to my css
scss: webroot + "scss/", //path to my scss src files
destJs: webroot + "js/", //path to my js source files (also the destination)
lib: webroot + "/lib/" //path to my lib folder for storing libraries
};
//build both the dev and production styles
gulp.task('build-styles', function (done) {
return runSequence(["build-styles-dev", "build-styles-prod"]);
});
//sass transforms all my scss files individually (producing separate css files for each library I am using)
gulp.task('build-styles-dev', function () {
var sassOptions = {
errLogToConsole: true,
outputStyle: 'expanded',
sourceMap: true
};
return gulp.src([ //include all my libraries css files that isn't sass based in the front of the stream
paths.lib + '/angular-loading-bar/build/loading-bar.css',
paths.lib + '/angular-toastr/dist/angular-toastr.css',
paths.lib + '/angular-ui-select/dist/select.css',
paths.lib + '/angular-ui-tree/dist/angular-ui-tree.css',
paths.lib + '/tether/dist/css/tether.css',
paths.lib + '/tether/dist/css/tether-theme-basic.css',
paths.scss + '/site.scss' //my sass file (does imports etc in it)
])
.pipe(sass({ errLogToConsole: true, outputStyle: 'expanded', sourceMap: true }).on('error', sass.logError))
.pipe(autoprefixer()) //autoprefix browser specific css
.pipe(gulp.dest(paths.css)) //output all the sass and auto prefixed css files based on the source
.resume();
});
//same as above task except this one doesn't output the individual files. It concats them all together into one file, compresses it, and generates the source maps for it.
gulp.task('build-styles-prod', function () {
var sassOptions = {
errLogToConsole: true,
outputStyle: 'expanded',
sourceMap: true
};
return gulp.src([
paths.lib + '/angular-loading-bar/build/loading-bar.css',
paths.lib + '/angular-toastr/dist/angular-toastr.css',
paths.lib + '/angular-ui-select/dist/select.css',
paths.lib + '/angular-ui-tree/dist/angular-ui-tree.css',
paths.lib + '/tether/dist/css/tether.css',
paths.lib + '/tether/dist/css/tether-theme-basic.css',
paths.scss + '/site.scss'
])
.pipe(sass({ errLogToConsole: true, outputStyle: 'expanded', sourceMap: true }).on('error', sass.logError))
.pipe(autoprefixer())
.pipe(concat("compiled.css"))
.pipe(gulp.dest(paths.css))
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(cleanCss())
.pipe(rename({ suffix: '.min' }))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(paths.css))
.resume();
});
//grabs all the library scripts and compresses them into one js file
gulp.task('build-scripts', function () {
return gulp.src([
paths.lib + 'jquery/dist/jquery.js',
paths.lib + 'tether/dist/js/tether.js',
paths.lib + 'angular/angular.js',
paths.lib + 'angular-messages/angular-messages.js',
paths.lib + 'angular-animate/angular-animate.js',
paths.lib + 'angular-cookies/angular-cookies.js',
paths.lib + 'angular-chart/angular-chart.js',
paths.lib + 'angular-loading-bar/build/loading-bar.js',
paths.lib + 'angular-toastr/dist/angular-toastr.js',
paths.lib + 'angular-sanitize/angular-sanitize.js',
paths.lib + 'angular-ui-router/release/angular-ui-router.js',
paths.lib + 'angular-ui-select/dist/select.js',
paths.lib + 'angular-ui-tree/dist/angular-ui-tree.js',
paths.lib + 'bootstrap/dist/js/bootstrap.js',
paths.js + 'app.js', //Load app.js first
paths.js + 'services/**/*.js', //Load all angular services next
paths.js + 'directives/**/*.js', //load directives after services
paths.js + 'controllers/**/*.js', //load angular controllers last after services and directives
paths.js + 'appLast.js', //A tail script I have load last for end of page logic, preventing the need for me to use document ready since this loads in the page footer.
])
.pipe(sourcemaps.init())
.pipe(gulp.dest(paths.destJs)) //output all the files individually (so file names need to be unique accross the whole system, generally not a problem)
.pipe(concat('scripts.js')) //concat all the scripts together into one file called scripts.js
.pipe(uglify()) //minimize all the scripts
.pipe(rename({ suffix: '.min' })) //rename to scripts.min.js
.pipe(sourcemaps.write('.')) //write the source maps
.pipe(gulp.dest(paths.destJs)); //output scripts.min.js
});
我的gulp文件中缺少的部分是应用程序脚本,它看起来像这样(尚未为此应用程序完成它)。