将现有JavaScript项目导入Grunt / Brunch项目

时间:2012-07-10 00:07:45

标签: javascript node.js brunch gruntjs

我看了Paul Irish的演讲,宣布了Yeoman(www.yeoman.io),我迷上了运行持续构建环境的概念。不满足于等待Yeoman邀请,我尝试了Grunt和Brunch。两者都很容易安装,我可以轻松地启动和运行新项目。

我不明白如何将现有项目迁移到任一平台。我的项目使用单个命名空间,并对模块使用两个约定(一个用于实例化另一个实例),每个约束都包含在导出实例或命名空间的自执行匿名函数中。

我至少有200个模块和更多简单的辅助函数导出到命名空间;因此,使用控制台在grunt / brunch项目中创建它们然后单独手动导入每个模块并不是一件有效的事情。此外,我使用至少15种不同的第三方JavaScript工具。我不清楚如何将它们带入。

以最少的重构和对任意第三方工具的支持,采用大型现有项目并将其迁移到Grunt / Brunch的最有效方法是什么?

更新:在这两者中,我发现Brunch更容易应对。如果您使用股票“骨架”(即“模板” - 从命令行{在您希望更改的文件夹中}执行“brunch new [project_name] --skeleton git://github.com/brunch /simple-js-skeleton.git“)对于纯JS,你得到一个新的文件夹结构,实际上是非常敏感的。您在“app”(您自己的代码)或“供应商”(第三方)文件夹中输入的任何内容都将在文件编辑时自动重新编译(当您运行“早午餐手表”时)。

这很好,除了。根据文档,您可以控制订单供应商脚本从Brunch config.coffee文件(JSON文本文件)编译和连接在一起。 对此文件的更改似乎没有任何效果,因此您最终会遇到期望其他插件的插件的第三方竞争条件。

此外,当您将自己的代码放入自动创建的“app”文件夹时,您会获得一个自动编译的,实时的编辑版代码;但它无法访问。早午餐会混淆窗口对象,因此我对window.myNameSpace的初始名称空间声明失败,并且对名称空间的所有后续库调用也会失败。这与Brunch的模块系统有关,我找不到任何文档。

我通过将我的命名空间类放在'vendor'文件夹中来解决这个问题,这确保了它附加到window对象;但是,现在存在竞争条件:我的命名空间并不总是可用于我的所有模块。

现在的问题是:

将所有内部和外部库复制到Brunch项目后,如何配置应用程序以合理的顺序加载它们?

2 个答案:

答案 0 :(得分:8)

这是一个作品,但我终于明白了。当我开始使用早午餐时,如何完成第一步并不明显:导入我的目录结构。在文档显而易见之前,我花了几遍文档:

  1. 执行brunch new MyAppName -s https://github.com/damassi/Javascript-App-Skeleton,它将生成一个框架文件夹结构和config.coffee文件
  2. 对我来说,这个结构中唯一相关的文件夹是'app'(CSS,JS和HTML的原始src内容),'public'(编译内容的目的地和服务NodeJS服务器的位置)和'供应商' '(第三方文件的地方)。
  3. Brunch使用以下内容在目录结构的根目录下创建config.coffee文件:files: javascripts: defaultExtension: 'js' joinTo: 'javascripts/app.js': /^app/ 'javascripts/vendor.js': /^vendor/ order: before: [ 'vendor/scripts/console-helper.js', 'vendor/scripts/jquery-1.7.1.min.js' ]
  4. 这个对象的'joinTo'属性使我感到困惑,直到我意识到'javascripts'实际上只是'客户端代码'的掩码,'apps.js'实际上是对'get all *'的调用。 js文件在“app”文件夹中,递归地'。
  5. 一旦清楚,您需要做的就是将内容放入“app”。我将* .html和图像文件放入'assets'子文件夹,并将我的所有JavaScript内容放入lib。
  6. 此时,您可以运行早午餐构建和早午餐监视,并且您的项目已启动并正在运行,在您进行更改时实时编译,在浏览器中实时重新加载。
  7. 虽然Brunch在使用第6步方面比Grunt更好,但对我来说失败的原因是Brunch的编译性质。每个JavaScript文件都包含在CommonJS模块中,模块名称基于相对路径和文件名('lib / core / ajax'等)。 CommonJS哲学不适合我,而且重构我的库以使用CommonJS所涉及的工作是巨大的。

    所以,回到Grunt。一旦我了解了如何将项目导入Brunch,导入Grunt就很容易了。我在Windows上,所以所有grunt调用都使用grunt.cmd。

    1. 调用grunt init:jquery(这可以是任何地方,我将创建的目录结构移动到我现有的项目文件夹中)
    2. 就像早午餐一样,你会得到一个自动生成的目录结构和配置文件(grunt.js),但它要薄得多。 Grunt的配置如下所示:concat: { dist: { src: ['<config:lint.files>'], dest: 'dist/<%= pkg.name %>.js' } }, min: { dist: { src: ['<banner:meta.banner>', '<config:concat.dist.dest>'], dest: 'dist/<%= pkg.name %>.min.js' } }, qunit: { files: ['test/**/*.html'] }, lint: { files: ['grunt.js', 'src/**/*.js', 'test/**/*.js'] }, watch: { files: '<config:lint.files>', tasks: 'lint qunit' }
    3. 起初看起来有些陌生,但实际上它非常优雅。 'min'属性定义了我的Web应用程序将提供的最终,连接,linted和minified文件。它的源值是'',这是Grunt魔术来查看concat对象的dist dest属性值的值,然后从lint的文件属性值派生。因此,您可以定义要在lint级别进行linted,连接,缩小和输出到目标的资源。
    4. 一旦这个部分到位,你必须做一些额外的工作来使构建,观察和服务器部件到位。在grunt中,当服务器完成执行时,它退出。这意味着如果您执行grunt服务器任务,它将启动服务器而没有其他任务要做,退出。
    5. 我的第一个错误是通过设置watch.task ='server lint qunit'将服务器任务与watch的任务捆绑在一起。这适用于您对源所做的第一次更改,但第二次更改将尝试在同一端口上启动服务器的第二个实例并失败。相反,您可以注册任务grunt.registerTask('dev', 'server watch qunit');并调用grunt dev以使服务器以实时连续构建运行。
    6. 接下来,我的HTML内容依赖于服务器端包含来组装页面。我无法弄清楚如何在Node中使用它,并且客户端包括使用<object/>不起作用,因为它们插入内容(在我的情况下是各种<script/>和{{1}在iframe中,这当然会破坏我的模块模式(我的命名空间与iframe的窗口对象位于不同的窗口对象中)。幸运的是,grunt的concat对象是一个多任务,它可以连接任何东西。所以我将我的HTML文件添加到concat中,我的单页应用程序已准备就绪。
    7. 接下来,因为Node服务器在与我的IIS实例不同的端口上运行,所以您遇到了跨域ajax问题。这个SO article让我走上了正确的道路,但我最终需要对IIS默认内容标题进行以下更改:<link/>
    8. 最后,因为我使用jQuery作为我的默认AJAX处理程序,所以我需要将它添加到我的ajax选项中:Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: X-Requested-With, X-Prototype-Version, Content-Type, Origin, Allow Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS Access-Control-Allow-Origin: http://localhost:88
    9. 显然,这里有安全隐患;但是因为这只会影响我的开发环境,不会被推到Production,我认为没关系。
    10. 最后但并非最不重要的是,我花了一个小时试图通过Uglify which was conveniently answered by this SO post调试缩小误差。由于Visual Studio坚持在整个节奏中插入BOM(“UTF-8 With Signature”是委婉语),但UTF-8 Cast以快速顺序修复此问题。
    11. 一旦我弄明白这一切,Grunt似乎工作得很好。我还没有机会在这个新的持续构建环境中开始测试实际的开发过程;但这就是能够开始的过程。

答案 1 :(得分:3)

config.coffee不是真正的json而不是真正的js / coffeescript,但订单编辑应该有效。你能用精确的配置顺序在brunch bugtracker中打开一个问题吗?

我认为没有一种快速的方法来重写您的应用程序以使用模块而不是全局window变量。顺便说一句,Globals被认为是一种不好的味道。但是你的解决方案可行,是的。