4

到目前为止,我的项目中只有一个 javascript 文件,其中包含大量函数,其中只有几个函数被多个网页使用。随着涉及的代码量增加,我可以看到文件变得混乱,而且方式也很混乱长。我正在考虑为每个网页创建一个单独的 javascript 文件,以便:

  1. 即使对于那些很少使用它的页面,我也不必加载一个巨大的 javascript 文件。
  2. 该文件不会变得更加混乱

但我不知道这是否会产生我不知道的负面影响。

4

4 回答 4

2

更少的文件导致更少的干净代码,这反过来意味着更慢的编码和更难调试。更多文件意味着更多 HTTP 请求和更慢的网站。因此,开发尽可能多的文件来组织代码并保持开发的可管理性。

于 2013-10-28T11:27:20.630 回答
2

这里有许多选项,纯粹集中在组织文件方面,如果你正在处理的内容相当大,那么值得考虑使用像require.js这样的库。 然而,这适用于应用程序,即使您可以轻松地将其用于其他事情,其想法是您将代码重组为独立模块,这在您的情况下可能是明智的,也可能不是明智的。

但是,如果我们正在谈论的 javascript与页面的内容紧密耦合,因此在它的设置中不能重复用于其他页面,那么使用内联<script>标签而不是外部 javascript 文件可能是非常正确的。

最后一点,require.js 或任何具有多个 javascript 的设置都会对 http 请求产生轻微的开销,但我不会担心太多。Require.js 或类似的库甚至会为你加载这个异步,所以总而言之,它可能比一个可能不会用于任何给定访问者的大部分文件的大文件更有效率(尽管这取决于访问者是否最终是否会访问所有页面)。

于 2013-10-28T11:31:14.883 回答
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.jsfile 作为您网站的入口点(index.html):

<script src="js/require.min.js" data-main="js/main.js"></script>
于 2013-10-28T11:27:29.653 回答
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 文件

/// <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 文件中缺少的部分是应用程序脚本,它看起来像这样(还没有为这个应用程序完成它)。

于 2016-08-22T21:29:51.887 回答