草庐IT

javascript - 将现有的 JavaScript 项目导入 Grunt/Brunch 项目

coder 2024-07-23 原文

我观看了 Paul Irish 宣布 Yeoman (www.yeoman.io) 的演讲,并且我对运行连续构建环境的概念非常着迷。不满足于等待 Yeoman 邀请,我尝试了 Grunt 和 Brunch。两者都可以轻松安装,而且我可以轻松启动并运行新项目。

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

我至少有 200 个模块和更多简单的辅助函数导出到命名空间;因此,使用控制台在 grunt/brunch 项目中创建这些,然后单独手动导入每个模块,效率并不高。此外,我使用了至少 15 种不同的第 3 方 JavaScript 工具。我不清楚如何引入这些。

使用最少的重构和对任意 3rd 方工具的支持,将大型现有项目迁移到 Grunt/Brunch 的最有效方法是什么?

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

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

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

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

现在的问题是这样的:

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

最佳答案

这有点不可思议,但我终于想通了。当我开始使用 Brunch 时,如何进行第一步并不明显:导入我的目录结构。在它变得明显之前,我花了几遍文档:

  • 执行 brunch new MyAppName -s https://github.com/damassi/Javascript-App-Skeleton ,这将生成一个骨架文件夹结构和 config.coffee 文件
  • 对我来说,此结构中唯一相关的文件夹是“app”(CSS、JS 和 HTML 的原始 src 内容)、“public”(编译内容的目的地和为 NodeJS 服务器提供服务的位置)和“vendor”( 3rd 方文件的位置)。
  • 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' ]
  • 这个对象的“joinTo”属性让我感到困惑,直到我意识到“javascripts”实际上只是“客户端代码”的掩码,而“apps.js”实际上是对“获取所有 *.js 文件”的调用文件夹“应用程序”,递归'。
  • 清楚这一点后,您所需要做的就是将您的内容放入“应用程序”中。我将 *.html 和图像文件放入“assets”子文件夹,并将所有 JavaScript 内容放入 lib。
  • 此时,您可以运行 brunch build 和 brunch watch,您的项目已启动并运行,在您进行更改时实时编译,在浏览器中实时重新加载。

  • 虽然 Brunch 在第 6 步的易用性方面比 Grunt 开箱即用更好,但对我来说失败的是 Brunch 编译的性质。每个 JavaScript 文件都包含在一个 CommonJS 模块中,模块名称基于相对路径和文件名(“lib/core/ajax”等)。 CommonJS 哲学不适合我,重构我的库以使用 CommonJS 所涉及的工作是巨大的。

    所以,回到 Grunt。一旦我了解了如何将项目导入 Brunch,导入 Grunt 就变得轻而易举了。我在 Windows 上,所以所有 grunt 调用都使用 grunt.cmd。
  • 调用 grunt init:jquery (这可以在任何地方,我将创建的目录结构移动到我现有的项目文件夹中)
  • 像 Brunch 一样,你会得到一个自动生成的目录结构和配置文件 (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' }
  • 起初我觉得这有点陌生,但它实际上非常优雅。 'min' 属性定义了我的 Web 应用程序将提供的最终、连接、linted 和缩小的文件。它的源值是 '',这是 Grunt 的魔法,可以查看 concat 对象的 dist dest 属性值的值,然后从 lint 的文件的属性值中导出该值。因此,您可以在 lint 级别定义要被 lint、连接、缩小并输出到目标的资源。
  • 一旦这部分就位,您必须做一些额外的工作来使构建、监视和服务器部分就位。在 grunt 中,当服务器完成执行时,它会退出。这意味着如果您执行 grunt 服务器任务,它将启动服务器并且没有其他任务可做,退出。
  • 我的第一个错误是通过设置 watch.task = 'server lint qunit' 将服务器任务与 watch 的任务捆绑在一起。这适用于您对源所做的第一次更改,但第二次更改将尝试在同一端口上启动服务器的第二个实例并失败。相反,您可以注册一个任务 grunt.registerTask('dev', 'server watch qunit');并调用 grunt dev 让服务器实时、持续构建运行。
  • 接下来,我的 HTML 内容依赖于服务器端包含来组装页面。我不知道如何在 Node 中实现这一点,客户端包括使用 <object/>不起作用,因为它们将内容(在我的情况下是各种 <script/><link/> 元素)插入到 Iframe 中,这当然打破了我的模块模式(我的命名空间与iframe)。幸运的是,grunt 的 concat 对象是一个多任务,它可以连接任何东西。所以我将我的 HTML 文件添加到 concat,我的单页应用程序准备好了。
  • 接下来,因为 Node 服务器在与我的 IIS 实例不同的端口上运行,所以您遇到了跨域 ajax 问题。此 SO article让我走上了正确的道路,但我最终需要对 IIS 默认内容 header 进行以下更改: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
  • 最后,由于我将 jQuery 用于我的默认 AJAX 处理程序,我需要将它添加到我的 ajax 选项中:xhrFields: { withCredentials: true }
  • 显然,这里存在安全隐患;但由于这只会影响我的开发环境,不会被推送到生产环境,我认为没关系。
  • 最后但并非最不重要的是,我花了一个小时试图通过 Uglify 调试缩小错误,which was conveniently answered by this SO post .由于 Visual Studio 坚持在整个节奏中插入 BOM(“带签名的 UTF-8”是委婉说法),但 UTF-8 Cast快速修复此问题。

  • 一旦我弄清楚了所有这些,Grunt 似乎工作得很好。我还没有机会在这个新的持续构建环境中开始测试实际的开发过程;但这就是能够开始所需要的。

    关于javascript - 将现有的 JavaScript 项目导入 Grunt/Brunch 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11404971/

    有关javascript - 将现有的 JavaScript 项目导入 Grunt/Brunch 项目的更多相关文章

    1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

      如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

    2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

      我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

    3. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

      我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

    4. Ruby 从大范围中获取第 n 个项目 - 2

      假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

    5. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

      如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

    6. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

      我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

    7. ruby - 如何在 Ruby 字符串中插入项目符号字符? - 2

      我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195

    8. ruby - 在 Rails 项目中测试本地版本的 gem - 2

      我的Rails站点使用了一个确实不是很好的gem。每次我需要做一些新的事情时,我最终不得不花费与向实际Rails项目添加代码一样多的时间来为gem添加功能。但我不介意,我将我的Gemfile设置为指向我的gem的GitHub分支(我尝试提交PR,但维护者似乎已经下台)。问题是我真的没有找到一种合理的方法来测试我添加到gem的新东西。在railsc中测试它会特别好,但我能想到的唯一方法是a)更改~/.rvm/gems/.../foo。rb,这看起来不对或者b)升级版本,推送到Github,然后运行​​bundleup,这除了耗时之外显然是一场灾难,因为我不确定我所做的promise是否正

    9. ruby-on-rails - 在现有数据库上进行 Rails 迁移 - 2

      我正在创建一个新的Rails3.1应用程序。我希望这个新应用程序重用现有数据库(由以前的Rails2应用程序创建)。我创建了新的应用程序定义模型,它重用了数据库中的一些现有数据。在开发和测试阶段,一切正常,因为它在干净的表数据库上运行,但是当尝试部署到生产环境时,我收到如下消息:PGError:ERROR:column"email"ofrelation"users"alreadyexists***[err::localhost]:ALTERTABLE"users"ADDCOLUMN"email"charactervarying(255)DEFAULT''NOTNULL但是我在迁移中有这

    10. ruby - 如何将新的 rvm 安装与现有的 ruby​​ 版本相关联? - 2

      我遇到了RVM的问题,所以我卸载并重新安装了它。事实是我实际上尝试过rbenv,但这对我来说没有用,所以我试图让rvm重新启动并运行-而不必安装重复版本的Ruby。我至少安装了1个现有版本的Ruby:ruby--versionruby1.8.7(2011-12-28patchlevel357)[universal-darwin11.0]但是当我执行rvmlist时,我得到一个空白列表:bash-3.2$rvmlistrvmrubies#Defaultrubynotset.Try'rvmaliascreatedefault'.#=>-current#=*-current&&default

    随机推荐