web-dev-qa-db-fra.com

Utiliser Gulp pour construire le projet requireJS - gulp-requirejs

J'essaie d'utiliser gulp-requirejs pour construire un projet de démonstration. Je m'attends à ce que le résultat soit un fichier unique avec toutes les dépendances et le modèle inclus. Voici mon gulpfile.js

var gulp = require('gulp');
var rjs = require('gulp-requirejs');
var paths = {
  scripts: ['app/**/*.js'],
  images: 'app/img/**/*'
};

gulp.task('requirejsBuild', function() {
    rjs({
        name: 'main',
        baseUrl: './app',
        out: 'result.js'
    })
    .pipe(gulp.dest('app/dist'));

});

// The default task (called when you run `gulp` from cli)
gulp.task('default', ['requirejsBuild']);

Le fichier de construction ci-dessus fonctionne sans erreur, mais le fichier result.js ne contient que le contenu de main.js et de config.js. Tous les fichiers d’affichage, jquery, underscore, backbone ne sont pas inclus. 

Comment configurer gulp-requirejs pour qu'il mette tous les modèles js dans un fichier js? Si ce n’est pas la bonne façon de faire, pouvez-vous suggérer une autre méthode? 

Modifier

config.js

require.config({
    paths: {
        "almond": "/bower_components/almond/almond",
        "underscore": "/bower_components/lodash/dist/lodash.underscore",
        "jquery": "/bower_components/jquery/dist/jquery",
        "backbone": "/bower_components/backbone/backbone",
        "text":"/bower_components/requirejs-text/text",
        "book": "./model-book"
    }
});

main.js

// Break out the application running from the configuration definition to
// assist with testing.
require(["config"], function() {
    // Kick off the application.
    require(["app", "router"], function(app, Router) {
        // Define your master router on the application namespace and trigger all
        // navigation from this instance.
        app.router = new Router();

        // Trigger the initial route and enable HTML5 History API support, set the
        // root folder to '/' by default.  Change in app.js.
        Backbone.history.start({ pushState: false, root: '/' });
    });
});

La sortie n'est qu'une combinaison de ces deux fichiers, ce qui n'est pas ce à quoi je m'attendais.

20
Nicolas S.Xu

gulp-requirejs a été mis sur la liste noire par les gens de gulp. Ils voient l'optimiseur RequireJS comme son propre système de construction, incompatible avec gulp. Je ne connais pas grand chose à ce sujet, mais j’ai trouvé une alternative dans AMD-optimize qui a fonctionné pour moi.

npm install AMD-optimize --save-dev

Puis dans votre gulpfile:

var amdOptimize = require('AMD-optimize');
var concat = require('gulp-concat');

gulp.task('bundle', function ()
{
    return gulp.src('**/*.js')
        .pipe(amdOptimize('main'))
        .pipe(concat('main-bundle.js'))
        .pipe(gulp.dest('dist'));
});

La sortie de amdOptimize est un flux contenant les dépendances du module principal (main dans l'exemple ci-dessus) dans un ordre résolu correctement lors du chargement. Ces fichiers sont ensuite concaténés via concat dans un seul fichier main-bundle.js avant d’être écrits dans le dossier dist.

Vous pouvez également réduire ce fichier et effectuer d'autres transformations si nécessaire.


En passant, dans mon cas, je compilais TypeScript dans des modules AMD pour les regrouper. En réfléchissant davantage, je me suis rendu compte que pour tout regrouper, je n'ai pas besoin du chargement asynchrone fourni par AMD/RequireJS. Je vais plutôt essayer de compiler les modules CommonJS de TypeScript, puis de les regrouper avec webpack ou browserify , qui semblent tous deux bien pris en charge par gulp.

31
Drew Noakes

METTRE À JOUR

Ma réponse précédente signalait toujours taskReady, même si requirejs signalait une erreur. J'ai reconsidéré cette approche et ajouté l'enregistrement des erreurs. Aussi, j'essaie de faire échouer la construction complètement comme décrit ici gulp-jshint: Comment faire échouer la construction? car un échec silencieux consomme vraiment votre temps ... Voir le code mis à jour ci-dessous.

Le commentaire de Drew à propos de la liste noire était très utile et beaucoup de gens suggèrent d’utiliser directement requirejs. Je publie donc directement ma solution requirejs:

var DIST = './dist';
var requirejs = require('requirejs');
var requirejsConfig = require('./requireConfig.js').RJSConfig;

gulp.task('requirejs', function (taskReady) {
    requirejsConfig.name = 'index';
    requirejsConfig.out = DIST + 'app.js';
    requirejsConfig.optimize = 'uglify';
    requirejs.optimize(requirejsConfig, function () {
        taskReady();
    }, function (error) {
        console.error('requirejs task failed', JSON.stringify(error))
        process.exit(1);
    });
});

Le fichier à ./dist/app.js est construit et mis à jour. Et de cette façon, gulp saura quand la construction sera terminée. Donc, la tâche peut être utilisée comme dépendance.

10
Olga

Ma solution fonctionne comme ceci:

./client/js/main.js:

require.config({
    paths: {
        jquery: "../vendor/jquery/dist/jquery",
        ...
    },
    shim: {
        ...
    }
});

define(["jquery"], function($) {
    console.log($);
});

./gulpfile.js:

var gulp = require('gulp'),
    ....
    amdOptimize = require("AMD-optimize"),
    concat = require('gulp-concat'),
    ...

gulp.task('scripts', function(cb) {

    var js = gulp.src(path.scripts + '.js')
        .pipe(cached('scripts'))
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(remember('scripts'))
        .pipe(amdOptimize("main",
            {
                name: "main",
                configFile: "./client/js/main.js",
                baseUrl: './client/js'
            }
        ))
        .pipe(concat('main.js'));

        .pipe(gulp.dest(path.destScripts));
}
...

Cette partie était importante:

configFile: "./client/js/main.js",
baseUrl: './client/js'

Cela m'a permis de garder ma configuration au même endroit. Sinon, je devais dupliquer mes chemins et mes cales dans gulpfile.js.

5
Henry

Désolé pour mon anglais. Cette solution fonctionne pour moi. (J'ai utilisé gulp-requirejs à mon travail)

Je pense que vous avez oublié de définir mainConfigFile dans votre fichier gulpfile.js. Donc, ce code sera un travail

gulp.task('requirejsBuild', function() {
    rjs({
        name: 'main',
        mainConfigFile: 'path_to_config/config.js',
        baseUrl: './app',
        out: 'result.js'
    })
    .pipe(gulp.dest('app/dist'));

});

En outre, je pense que lorsque vous exécutez cette tâche dans gulp, require ne peut pas trouver son fichier de configuration et 

1
FedeF

Ce n'est pas faute gulp-requirejs.

La raison pour laquelle seuls main.js et config.js se trouvent dans la sortie est que vous ne nécessitez/définissez aucun autre fichier. Sans cela, l’optimiseur require ne comprendra pas quels fichiers ajouter, les chemins dans votre fichier de configuration ne sont pas un moyen de les exiger!

Par exemple, vous pouvez charger un fichier main.js à partir de votre fichier de configuration et définir tous vos fichiers (pas optimal, mais juste un exemple). 

Au bas de votre fichier de configuration:

// Load the main app module to start the app
requirejs(["main"]); 

Le fichier main.js: (ajoute juste jquery pour montrer la technique.

define(["jquery"], function($) {}); 

Je pourrais aussi recommander plutôt gulp-requirejs-optim, principalement parce qu’il ajoute les fonctions de minification/obfuscation qui manquent à gulp-requirejs: https://github.com/jlouns/gulp-requirejs-optimize

Comment l'implémenter:

var requirejsOptimize = require('gulp-requirejs-optimize');

gulp.task('requirejsoptimize', function () {
  return gulp.src('src/js/require.config.js')
    .pipe(requirejsOptimize(function(file) {
      return {
        baseUrl: "src/js",
        mainConfigFile: 'src/js/require.config.js',
        paths: {
          requireLib: "vendor/require/require"
        },
        include: "requireLib",
        name: "require.config",
        out: "dist/js/bundle2.js"
      };
  })).pipe(gulp.dest(''));
});
1
Per Thomasson

Essayez ce code dans votre fichier gulp:

// Node modules
var
    fs = require('fs'),
    vm = require('vm'),
    merge = require('deeply');    

// Gulp and plugins
var
    gulp = require('gulp'),    
    gulprjs= require('gulp-requirejs-bundler');

// Config
var
    requireJsRuntimeConfig = vm.runInNewContext(fs.readFileSync('app/config.js') + '; require;'),
    requireJsOptimizerConfig = merge(requireJsRuntimeConfig, {
        name: 'main',
        baseUrl: './app',
        out: 'result.js',
        paths: {
            requireLib: 'bower_modules/requirejs/require'
        },
        insertRequire: ['main'],
        // aliases from config.js - libs will be included to result.js
        include: [
            'requireLib',
            "almond",
            "underscore",
            "jquery",
            "backbone",
            "text",
            "book"
        ]
    });

gulp.task('requirejsBuild', ['component-scripts', 'external-scripts'], function (cb) {
    return gulprjs(requireJsOptimizerConfig)            
        .pipe(gulp.dest('app/dist'));
});
0
blazkovicz