使用grunt.js使用RequireJS组合JavaScript文件的工作项目结构?

Chr*_*alo 38 javascript build requirejs gruntjs

我有一些项目使用RequireJS在浏览器中加载单个JavaScript模块,但我还没有对它们进行优化.在开发和生产中,应用程序为每个JavaScript文件单独发出请求,现在我想使用Grunt修复它.

我试图将一个简单的项目结构组合起来无济于事,所以我想知道是否有人可以为我提供一个有效的例子.我的目标如下:

  1. 在开发模式中,通过为每个所需模块发出单独的请求,一切都在浏览器中工作.在开发模式下不需要任何繁琐的任务或连接.
  2. 当我准备好了,我可以运行一个繁琐的任务来使用r.js优化(组合)所有JavaScript文件并在本地测试.一旦我确信优化的应用程序正确运行,我就可以部署它.

以下是为了进行此对话的示例结构:

grunt-requirejs-example/
  grunt.js
  main.js (application entry point)
  index.html (references main.js)
  lib/ (stuff that main.js depends on)
    a.js
    b.js
    requirejs/
      require.js
      text.js
  build/ (optimized app goes here)
  node_modules/ (necessary grunt tasks live here)
Run Code Online (Sandbox Code Playgroud)

具体来说,我正在寻找一个可以从中开始的工作项目结构.我的主要问题是:

  1. 如果这个项目结构存在缺陷,你会推荐什么?
  2. 我的grunt.js文件中究竟需要什么,尤其是让r.js优化器工作?
  3. 如果所有这些都不值得工作,并且有一种方法可以使用grunt watch任务在每次保存文件时自动构建开发模式中的所有内容,那么我全都听见了.我想避免任何减慢循环的事情从进行更改到在浏览器中看到它.

Mar*_*one 81

我使用grunt-contrib-requirejs任务来构建基于require.js的项目.使用以下命令在项目目录中安装它:

npm install grunt-contrib-requirejs --save-dev
Run Code Online (Sandbox Code Playgroud)

BTW:--save-dev将包添加到package.json中的开发依赖项中.如果您未在项目中使用package.json,请忽略它.

使用以下命令在grunt文件中加载任务:

grunt.loadNpmTasks('grunt-contrib-requirejs');
Run Code Online (Sandbox Code Playgroud)

并将配置添加到您的grunt.initConfig

requirejs: {
  production: {
    options: {
      baseUrl: "path/to/base",
      mainConfigFile: "path/to/config.js",
      out: "path/to/optimized.js"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以将require.js内容构建到单个文件中,该文件将通过运行uglifyjs进行最小化 grunt requirejs

您可以将一组不同的任务捆绑到某种主要任务中,方法是将其添加到您的grunt文件中

grunt.registerTask('default', ['lint', 'requirejs']); 
Run Code Online (Sandbox Code Playgroud)

有了这个,你可以简单地输入grunt和grunt将使用两个'子任务'自动运行默认任务:lint和requirejs.

如果您需要特殊的生产任务:如上所述定义它

grunt.registerTask('production', ['lint', 'requirejs', 'less', 'copy']);
Run Code Online (Sandbox Code Playgroud)

并运行它

grunt production
Run Code Online (Sandbox Code Playgroud)

如果你需要内部的'生产'和'开发'的不同行为,即requirejs任务,你可以使用所谓的目标.在上面的配置示例中,它已被定义为production.如果需要,可以添加另一个目标(顺便说一句,您可以通过在同一级别添加选项对象来为所有目标定义全局配置)

requirejs: {
  // global config
  options: {
    baseUrl: "path/to/base",
    mainConfigFile: "path/to/config.js"
  },
  production: {
    // overwrites the default config above
    options: {
      out: "path/to/production.js"
    }
  },
  development: {
    // overwrites the default config above
    options: {
      out: "path/to/development.js",
      optimize: none // no minification
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,您既可以同时使用它们,也可以grunt requirejs单独使用它们来运行它们grunt requirejs:production,或者在不同的任务中定义它们:

grunt.registerTask('production', ['lint', 'requirejs:production']);
grunt.registerTask('development', ['lint', 'requirejs:development']);
Run Code Online (Sandbox Code Playgroud)

现在回答你的问题:

  1. 我肯定会在你的项目中使用一个子文件夹.在我的情况下,我使用'src'文件夹进行开发,该文件夹构建到'htdocs'文件夹中进行生产.我喜欢的项目布局是:

    project/
      src/
        js/
          libs/
            jquery.js
            ...
          appname/
            a.js
            b.js
            ...
          main.js // require.js starter
        index.html
        ...
      build/
        ... //some tmp folder for the build process
      htdocs/
        ... // production build
      node_modules/
        ...
      .gitignore
      grunt.js
      package.json
    
    Run Code Online (Sandbox Code Playgroud)
  2. 往上看

  3. 你可以这样做,但我不建议在监视任务中添加requirejs,这是一项资源匮乏的任务,它会使你的机器变得明显变慢.

最后但同样重要的是:在玩r.js时要非常谨慎.特别是当您想通过向modules配置添加指令来使用r.js优化整个项目时.R.js会在不询问的情况下删除输出目录.如果发生意外配置为您的系统root,则r.js将清除您的HDD.请注意,我在设置我的grunt任务时永久删除了我的整个htdocs文件夹... keepBuildDir:true在使用r.js配置时总是添加到您的选项中.

  • 很好的答案 - 这是比我在其他任何地方找到的更好的建议. (3认同)
  • 我一直收到错误:缺少"名称","包含"或"模块"选项 (2认同)