如何管理客户端JavaScript依赖项?

时间:2012-10-15 09:45:21

标签: javascript npm coffeescript dependency-management

虽然有很好的解决方案来管理服务器端的依赖关系,但我找不到满足我所有需求的任何方法来建立一致的客户端JavaScript依赖关系管理工作流程。我想满足这5个要求:

  1. 以类似于npm的package.jsonbowerbower.json
  2. 的格式管理我的客户端依赖项
  3. 应该可以灵活地指向我的dependency.json文件中的git repo或实际js文件(无论是在网络上还是在本地),用于鲜为人知的库(npm让你指向git repos)
  4. 它应该将所有库缩小并命名为单个文件,如ender - 这是我需要在客户端<script>标记中放入的唯一js文件
  5. 应该像BoxJS 4(现已死)一样对CoffeeScript提供开箱即用支持
  6. 在浏览器中,我应该可以使用require样式:

    var $ = require('jquery');
    var _ = require('underscore');
    

    或者更好的是,做headjs样式:

    head.js(['jquery', 'underscore', 'mylib'], function($, _, mylib) {
      // executed when all libraries are loaded
    });
    
  7. 如果不存在这样的单一工具,那么什么是最好的工具组合,即我可以使用volo(或grunt)之类的东西组合的工具链?

    我已经研究过我在这里链接过的所有工具,他们最多只能满足我最多3个要求。所以,请不要再发布这些工具。我只接受一个答案,提供满足我所有5个要求的单一工具,或者如果有人发布了具有多个此类工具的工具链的具体工作流程/脚本/工作示例,这些工具也满足我的所有要求。谢谢。

16 个答案:

答案 0 :(得分:41)

require.js可以完成您需要的一切。

我对 this 问题的回答可能会对您有所帮助

示例:

客户端应用项目层次结构:

sampleapp
    |___ main.js
    |___ cs.js
    |___ require.js

main.js 是初始化客户端应用程序并配置require.js的地方:

require.config({
    baseUrl: "/sampleapp",
    paths: {
        jquery: "libs/jquery", // Local
        underscore: "http://underscorejs.org/underscore-min.js", // Remote
        backbone: "https://github.com/documentcloud/backbone/blob/master/backbone-min.js" // Remote on github
    },
    shim: {
        backbone: {
            deps: ["underscore", "jquery"] // Backbone depends on jquery and underscore
        }
    }
});

require(["cs!someCoffeescriptFile", "jquery", "backbone", "underscore"], function (SomeCoffeescriptFile, $, Backbone, _) {
    // Dependencies are loaded...
    // Execute code
});

依赖关系将在“cs!”前面加上cs插件。 cs插件编译coffeescript文件。

当您进入prod时,您可以使用r.js预编译整个项目。

node ./node_modules/requirejs/bin/r.js -o buildclientconfig.js

以下是您的要求:

  • 以类似于npm的格式管理我的客户端依赖项 package.json或bower的component.json。 不同但很好!

  • 我应该可以灵活地指向git repo或实际的js    我的dependency.json文件中的文件(在web或本地)    鲜为人知的图书馆(npm让你指向git repos)。的

  • 它应该将所有库缩小并命名为单个文件,如    ender - 这是我需要放在脚本标签中的唯一js文件    在客户端。 与r.js。

  • 它应该像Box一样支持coffeescript。的

  • 在浏览器中,我可以使用require style或headjs。的

答案 1 :(得分:24)

http://requirejs.org/是您正在寻找的我相信

答案 2 :(得分:15)

作为@ Guillaume86,我认为下摆会让你最接近你想去的地方。

在下摆依赖性中使用npm和hem的组合进行管理。使用npm 显式安装所有项目的外部依赖项。使用 要指定哪些依赖项(包括外部和本地) 为客户端操作缝合在一起。

我创建了一个这样的骨架项目,这样你就可以看到它是如何工作的 - 你可以在https://github.com/dsummersl/clientsidehem看到它

添加依赖项

使用npm搜索特定的依赖项,然后修改package.json file以确保将来跟踪依赖项。然后指定 你的应用程序依赖于slug.json。

例如,假设您要添加coffee-script依赖项。只需使用npm 安装依赖项并将其保存到package.json文件:

1. npm --save install coffee-script
2. Manually edit the slug.json file. Add "coffee-script" to "dependencies".

假设您想要包含自己的模块'bloomfilters',它不在npm注册表中。您可以通过以下方式将其添加到项目中:

1. npm --save install https://github.com/dsummersl/bloomfilters/tarball/master
2. Manually edit the slug.json file. Add "bloomfilters" to "dependencies".

本地模块

如果您想加入自己的咖啡或javascript,可以添加 那些文件到app /文件夹。请注意,为了通过公开您的脚本 'require'方法必须使它成为CommonJS模块。这很简单 - 见the hem docs

本地文件

如果你想要包含非CommonJS非'require'代码,你也可以拼接它 通过“libs”列表引用您的自定义javascript或coffeescript slug.json。

CSS

如果你愿意的话,哼也会把你的CSS拼接在一起。请参阅the hem docs

建筑

列出您的依赖项后,您可以使用折边将它们拼接在一起。

# make sure all dependencies are present:
npm install .
# make public/application.js
hem build
# see your minified js in public/application.js

备注

哼哼是为了spinejs项目 - 但你没有 必须使用它。忽略任何提及脊柱的文档......

答案 3 :(得分:11)

好吧,我很惊讶没有人提到Browserify

  1. 支持package.json格式
  2. 使用下面的npm,可以使用github(或任何git)repo作为包源
  3. 将所有依赖项缩小并连接到一个文件中。
  4. 支持coffeescript(如果将其包含在依赖项中)
  5. 一直需要风格。
  6. 支持源地图

答案 4 :(得分:9)

我非常确定Hem符合您的要求(我使用带有额外编译器的个人叉子 - 玉器和手写笔 - 可以根据您的需求轻松定制)。它使用npm来管理依赖项。

答案 5 :(得分:5)

您可能需要查看 Yeoman ,它使用多种技术来帮助您满足您的要求。

  

我们的工作流程包含三个改善您的工作流程的工具   构建Web应用程序时的工作效率和满意度:yo(   脚手架工具),grunt(构建工具)和bower(用于包   管理)。

内置对CoffeeScript,Compass等的支持。适用于r.js(RequireJS),单元测试等。

至于你的要求:

  1. Bower用于依赖管理
  2. Bower可以使用本地文件,git://,http://和更多
  3. 内置支持缩小和连接(即使是您的图像)
  4. 内置支持自动编译CoffeeScript&amp;指南针(使用LiveReload)
  5. 如构建过程中所述:如果您使用的是AMD,我会通过r.js传递这些模块,因此您不必这样做。
  6. 所有功能:

      

    Lightning-fast scaffolding - 轻松搭建新项目   可自定义的模板(例如HTML5 Boilerplate,Twitter Bootstrap),   RequireJS等。

         

    优秀的构建过程 - 您不仅可以获得   缩小和连接;我还优化了你的所有图像文件,   HTML,编译你的CoffeeScript和Compass文件,如果你正在使用的话   AMD,我将通过r.js传递这些模块,所以你没必要。

         

    自动编译CoffeeScript&amp;指南针 - 我们的LiveReload手表   进程自动编译源文件并刷新浏览器   无论何时进行更改,您都不必这样做。

         

    自动对脚本进行lint - 所有脚本都会自动针对JSHint运行,以确保它们遵循语言最佳实践。

         

    内置预览服务器 - 不再需要启动自己的HTTP服务器。我的内置   只用一个命令即可解雇一个。

         

    令人敬畏的图片优化 - 我使用OptiPNG和JPEGTran优化您的所有图片,因此您的用户可以花更少的时间下载资源,并花更多时间使用您的应用。

         

    杀手包管理 - 需要依赖吗?这只是一次击键   远。我允许您通过简单地搜索新包   命令行(例如`bower search jquery),安装它们并保留它们   无需打开浏览器即可更新。

         

    PhantomJS单元测试 - 通过PhantomJS在无头WebKit中轻松运行单元测试。什么时候   你创建一个新的应用程序,我还包括一些测试脚手架   你的应用。

答案 6 :(得分:4)

Bower可能适合您的需要(1)和(2)以满足您的需求。 从自述文件:

Bower is a package manager for the web. Bower lets you easily install assets such as images, CSS and JavaScript, and manages dependencies for you.

安装包:

bower install jquery
bower install git://github.com/maccman/package-jquery.git
bower install http://code.jquery.com/jquery-1.7.2.js
bower install ./repos/jquery

答案 7 :(得分:2)

看看Jam package manager。以下是其主页的描述

  

对于渴望可维护资产的前端开发人员,Jam是JavaScript的包管理器。与其他存储库不同,我们将浏览器放在首位。

它的工作原理与npm相似。

安装包如下

jam install backbone

通过执行

保持包最新
jam upgrade
jam upgrade {package} 

优化生产包

jam compile compiled.min.js

可以在package.json文件中添加Jam依赖项。

有关完整文档,请阅读Jam Documentation

答案 8 :(得分:2)

我刚遇到inject.js

部分功能来自project site

  

注入(Apache Software License 2.0)是一种以库不可知方式管理依赖关系的革命性方法。它的一些主要功能包括:

     
      
  • 浏览器中的CommonJS合规性(exports。*)
  •   
  • 查看完整的CommonJS支持矩阵
  •   
  • 跨域检索文件(通过easyXDM)
  •   
  • localStorage(加载模块一次)
  •   

答案 9 :(得分:1)

有几种选择:

Component也可能是有意义的,它本身不管理依赖项,但允许您使用其他大型库的切碎版本。

答案 10 :(得分:1)

我使用npm的下摆,我想添加一些我认为到目前为止尚未涵盖的额外好处。

  • Hem有一个独立的Web服务器(分层),因此您可以开发代码,甚至无需重新编译。除非我发布应用,否则我永远不会使用hem build
  • 您不需要使用Spine.js来使用下摆,如果正确设置了slug.json,您可以使用它来编译任意coffeescript包。这是我的一个使用cakefile自动编译的包:https://github.com/HarvardEconCS/TurkServer/tree/master/turkserver-js-client
  • 说到上面的内容,hem允许您使用npm链接链接本地系统上的其他依赖项,并且即使在使用分层服务器时也可以无缝地将它们组合在一起。事实上,你甚至不需要使用上面的cake方法,你可以直接链接到依赖项目的coffeescript。
  • Hem支持eco(嵌入式Coffeescript)for views和Stylus for CSS,并将所有这些与Coffeescript一起编译成一个JS和一个CSS文件。

这是使用Spine,hem,coffeescript应用设置的基本列表。随意忽略脊柱部分。实际上,有时我使用spine app为非Spine应用程序设置目录结构,然后编辑slug.json以更改为不同的编译结构。

  1. 在* nix系统上安装NPM:curl http://npmjs.org/install.sh | sh。我假设它可以从命令行获得。
  2. 全局安装下摆(npm install -g hem)。开发已经分支,因此您可能希望直接从github(https://github.com/spine/hem),结帐分支和该文件夹中的npm install -g .中获取。
  3. npm install -g spine.app将使脊椎可用作全局命令
  4. spine app folder将在app中创建一个名为folder的Spine项目,生成正确的目录结构和一堆骨架文件,以便开始使用。
  5. cd到文件夹并编辑dependencies.json以获取所需的库。将它们添加到slug.json,以便下摆知道在哪里找到它们。
  6. 可选:npm link您正在开发的任何本地软件包node_modules,您可以将它们添加到slug.json下方(要index.js直接包含或index.coffee如果你想要下摆来编译它。)
  7. npm install .下载您刚刚输入的所有依赖项。
  8. 如果你看一下默认的脊椎动态配置,你可以app/lib/setup.coffee require从依赖项中获取所需的所有库。例子:

    # Spine.app had these as dependencies by default
    require('json2ify')
    require('es5-shimify')
    require('jqueryify')
    
    require('spine')
    require('spine/lib/local')
    require('spine/lib/ajax')
    require('spine/lib/manager')
    require('spine/lib/route')
    
    # d3 was installed via dependencies.json
    require 'd3/d3.v2'
    
  9. index.coffee中,您只需require lib/setup并为您的应用加载主控制器。此外,您需要require其他控制器中的任何其他类。您可以使用spine controller somethingspine model something为控制器和模型生成模板。使用节点require

    ,典型的Spine控制器如下所示
    Spine = require('spine')
    # Require other controllers
    Payment = require('controllers/payment')
    
    class Header extends Spine.Controller
      constructor: ->
        # initialize the class
    
      active: ->
        super
        @render()
    
      render: ->
        # Pull down some eco files
        @html require('views/header')   
    
    # Makes this visible to other controllers    
    module.exports = Header
    
  10. 默认生成的index.html通常可以用于加载您的应用,但可以根据需要进行修改。根据您的要求,它只会提取一个js和一个css文件,您无需修改​​该文件。

  11. 根据需要在css文件夹中编辑手写笔文件。它比CSS更灵活:)
  12. folder开始,运行hem server以启动下摆服务器,然后导航至localhost:9294以查看您的应用。 (如果您在全局安装了hem。)它有一些隐藏的参数,例如--host 0.0.0.0侦听所有端口。
  13. 使用适当的MVC技术构建应用程序的其余部分,并使用手写笔用于CSS和eco用于视图。或者根本不使用Spine,下摆仍然可以与Coffeescript和npm一起使用。有许多使用这两种模型的项目示例。
  14. 还有一件事:通常,hem server会在您更新代码并保存文件时自动更新,这使得调试变得简单。运行hem build会将您的应用编译为两个文件application.js,该文件已缩小并application.css。如果您在此之后运行hem server,它将使用这些文件,不再自动更新。因此,在您真正需要缩小版本的应用程序进行部署之前,请不要hem build

    其他参考资料:Spine.js & hem getting started

答案 11 :(得分:1)

这是一个采用非常不同的方法的解决方案:将所有模块打包成JSON对象,并通过读取和执行文件内容而无需额外请求来获取模块。

纯客户端演示实施:http://strd6.github.io/editor/

https://github.com/STRd6/require/blob/master/main.coffee.md

STRd6 / require 取决于在运行时提供JSON包。为该包生成require函数。该软件包包含您的应用可能需要的所有文件。没有进一步的http请求,因为包捆绑了所有依赖项。这与客户端上的Node.js样式要求非常接近。

包的结构如下:

entryPoint: "main"
distribution:
  main: 
    content: "alert(\"It worked!\")"
  ...
dependencies:
  <name>: <a package>

与Node不同,包不知道它的外部名称。这取决于包括依赖命名的pacakge。这提供了完整的封装。

鉴于所有这些设置,这里是一个从包中加载文件的函数:

loadModule = (pkg, path) ->
  unless (file = pkg.distribution[path])
    throw "Could not find file at #{path} in #{pkg.name}" 

  program = file.content
  dirname = path.split(fileSeparator)[0...-1].join(fileSeparator)

  module =
    path: dirname
    exports: {}

  context =
    require: generateRequireFn(pkg, module)        
    global: global
    module: module
    exports: module.exports
    PACKAGE: pkg
    __filename: path
    __dirname: dirname

  args = Object.keys(context)
  values = args.map (name) -> context[name]

  Function(args..., program).apply(module, values)

  return module

此外部上下文提供了模块可以访问的一些变量。

require函数暴露给模块,因此它们可能需要其他模块。

其他属性,例如对全局对象的引用和一些元数据 也暴露了。

最后,我们在模块和给定的上下文中执行程序。

对于那些希望在浏览器中拥有同步node.js style require语句并且对远程脚本加载解决方案不感兴趣的人来说,这个答案最有帮助。

答案 12 :(得分:1)

如果您在后端使用node / express,请查看cartero

答案 13 :(得分:0)

我建议查看似乎符合您大部分要求的dojo toolkit。我不确定的是CoffeeScript。

dojo适用于以异步模块定义(AMD)格式编写的模块。它有一个带有包的构建系统,您可以将它们聚合在一个或多个文件(称为层)中。显然它接受git类型的存储库,这里有关于构建系统的更多细节:

http://dojotoolkit.org/documentation/tutorials/1.8/build/

据记载,预计下个月将推出v1.9测试版。

答案 14 :(得分:0)

满足我最近发布的所有标准的另一个框架:http://duojs.org/(并且还支持将CSS等其他资源视为依赖项)。

答案 15 :(得分:0)

使用异步加载+ browserify的依赖注入将是另一个不错的选择,与requirejs相比

asynchronous-frontend-dependency-management-without-AMD