38 votes

Structure de projet de travail utilisant grunt.js pour combiner des fichiers JavaScript avec RequireJS?

J'ai quelques projets qui utilisent RequireJS à charge individuelle des modules JavaScript dans le navigateur, mais je n'ai pas du tout optimisé encore. En développement et en production, l'application fait une demande distincte pour chaque fichier JavaScript, et maintenant, je tiens à corriger que l'utilisation de Grunt.

J'ai essayé de mettre sur pied un projet simple structure en vain, alors je me demandais si quelqu'un peut fournir un exemple pour moi. Mes objectifs sont les suivants:

  1. Le mode de développement, tout fonctionne dans le navigateur par l'émission d'une demande distincte pour chaque module. Aucun grognement de tâches ou de concaténation sont requis, le mode de développement.
  2. Quand je suis prêt, je peux exécuter une tâche grunt pour optimiser (combiner) tous les fichiers JavaScript à l'aide de r.js et test localement. Une fois que je suis convaincu de l'optimisation de l'application s'exécute correctement, je peux déployer.

Voici un exemple de structure pour le bien de cette conversation:

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)

Plus précisément, je suis à la recherche d'un travail de projet de la structure que je peux commencer à partir. Mes principales questions sont les suivantes:

  1. Si cette structure de projet est imparfait, que recommandez-vous?
  2. Ce qui doit exactement être dans ma grunt.js le fichier, en particulier pour obtenir la r.js optimiseur de travail?
  3. Si tout cela ne vaut pas le travail et il y a un moyen d'utiliser le grognement watch de la tâche pour construire automatiquement des tout, le mode de développement à chaque fois que j'enregistre un fichier, alors je suis tout oreilles. Je veux éviter tout ce qui ralentit la boucle de faire un changement à le voir dans le navigateur.

81voto

Marcello di Simone Points 1050

J'utilise le grunt-contrib-requirejs tâche de construire sur la base du projet require.js. L'installer à l'intérieur de votre répertoire de projet avec:

npm install grunt-contrib-requirejs --save-dev

BTW: --save-dev va ajouter à votre développement dépendances dans votre forfait.json. Si vous n'êtes pas à l'aide d'un package.json dans votre projet, de l'ignorer.

Charge de la tâche dans votre grunt fichier avec:

grunt.loadNpmTasks('grunt-contrib-requirejs');

Et ajouter la configuration de votre grunt.initConfig

requirejs: {
  production: {
    options: {
      baseUrl: "path/to/base",
      mainConfigFile: "path/to/config.js",
      out: "path/to/optimized.js"
    }
  }
}

Vous êtes maintenant en mesure de construire votre require.js des choses dans un seul fichier qui sera minimisé avec uglifyjs en exécutant grunt requirejs

Vous pouvez regrouper un ensemble de tâches différentes dans une sorte de tâche principale, en ajoutant ceci à votre fichier grunt

grunt.registerTask('default', 'lint requirejs'); 

Avec cela, vous pouvez simplement taper grunt et grunt va automatiquement exécuter la tâche par défaut avec les deux sous-tâches': les peluches et requirejs.

Si vous avez besoin d'une production spéciale de la tâche: la définissent comme ci-dessus

grunt.registerTask('production', 'lint requirejs less copy');

et de l'exécuter avec

grunt production

Si vous avez besoin de différents comportements pour la "production" et de "développement" à l'intérieur c'est à dire la requirejs tâche, vous pouvez utiliser des cibles. Dans l'exemple de configuration ci-dessus, c'est déjà définie comme production. Vous pouvez ajouter une autre cible si vous avez besoin d' (BTW, vous pouvez définir une config pour toutes les cibles par l'ajout d'un objet d'options sur le même niveau)

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
    }
  }
}

Maintenant, vous pouvez lancer les deux en même temps avec grunt requirejs ou individuel, avec grunt requirejs:production, ou de les définir dans les différentes tâches:

grunt.registerTask('production', 'lint requirejs:production');
grunt.registerTask('development', 'lint requirejs:development');

Maintenant, pour répondre à vos questions:

  1. Je serais certainement utiliser un sous-dossier de votre projet. Dans mon cas, j'utilise un 'src' dossier pour le développement, qui est de construire un "htdocs" dossier pour la production. Le projet de mise en page, je visez plutôt est:

    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
    
  2. voir ci-dessus

  3. Vous pouvez le faire, mais je ne recommanderais pas à ajouter requirejs pour la montre de la tâche, c'est une ressource faim et il va ralentir votre machine perceptible.

Dernier mais non le moindre: Être très prudent lors de la lecture autour de avec la r.js. Surtout quand vous voulez optimiser l'ensemble du projet avec r.js par l'ajout d'un modules directive à votre config. R. js va supprimer le répertoire de sortie sans demander. S'il arrive qu'elle soit accidentellement configuré pour être votre système racine, r.js va effacer de votre disque dur. Soyez averti, j'ai effacé tout mon répertoire htdocs définitivement il y a quelques temps lors de la configuration de ma tâche grunt... Toujours ajouter keepBuildDir:true de vos options lors de la lecture autour de avec la r.js config.

1voto

Daniel Points 416

J'ai eu une question similaire il y a quelque temps et j'ai utilisé une approche similaire à celle de Marcello. Vous pouvez voir le code de démonstration ici: https://github.com/swasical/backbone_require

Le principal problème est que requireJs a besoin de la structure de dossiers pour fonctionner correctement.

J'espère que le code est utile à quelqu'un.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X