2014-04-25 11 views
11

Próbuję zbudować aplikację SPA (requirejs, durandal 2, knockout) w pojedynczym pliku main-build.js za pomocą polecenia i "Występują poważne problemy z wtyczką" tekstową "używaną przez durandal do ładowania moich widoków.Użycie r.js do spakowania aplikacji SPA, która ładuje widoki za pomocą "tekstu"

W wersji deweloperskiej z powodzeniem używam "tekstu" do dynamicznego ładowania widoków zgodnie ze standardowym sposobem budowania durandalnych aplikacji. Różnica polega na tym, że muszę wykonać szablony po stronie serwera dla widoków i tak naprawdę są one generowane dynamicznie.

Mając to na uwadze, chciałbym użyć r.js do spakowania modeli aplikacji, przeglądania modeli i usług (za pomocą wtyczki grunt-durandal) do pojedynczego pliku, ale NIE pakować widoków (.html) i nadal ładuj je dynamicznie w razie potrzeby.

W mojej konfiguracji gruntowej używam opcji inlineText: false - co sprawdziłem, to tłumienie modułów "text! *" W kompilacji. Ale kiedy uruchomić aplikację Dostaję:

Uncaught TypeError: undefined is not a function od wewnątrz text.load na następującej linii:

var parsed = text.parseName(name), 
      nonStripName = parsed.moduleName + 
       (parsed.ext ? '.' + parsed.ext : ''), 
      url = req.toUrl(nonStripName), // EXCEPTION THROWN HERE 

Nazwa modułu ładowane wydaje się być prawidłowe (jego „!” Jeden tekst *) ale poza tym nie mam pojęcia, jak przystąpić do debugowania tego problemu. Co ja robię źle?

Moja grunt configuraiton jest:

/*global module, require */ 

module.exports = function (grunt) { 
'use strict'; 

// library that allows config objects to be merged together 
var mixIn = require('mout/object/mixIn'); 

var requireConfig = { 
    baseUrl: 'App/', 
    paths: { 
     'jquery': '../Scripts/jquery-2.1.0', 
     'knockout': '../Scripts/knockout-3.1.0', 
     'text': '../Scripts/text', 
     'durandal': '../Scripts/durandal', 
     'plugins': '../Scripts/durandal/plugins', 
     'transitions': '../Scripts/durandal/transitions', 
    } 
}; 

grunt.initConfig({ 
    pkg: grunt.file.readJSON('package.json'), 
    jshint: { 
     options: { 
      "-W099": true, // allowed mixed tabs and spaces 
      "-W004": true, // needed to avoid errors where TS fakes inheritance 
      ignores: [ 
       'App/main-built.js' // ingore the built/compacted file 
      ] 
     }, 
     all: [ // run jshint on these files 
      'gruntfile.js', 
      'App/**/*.js' 
     ] 
    }, 
    // TODO: could add jasmine here to do JS testing 
    clean: { 
     build: ['build/*'] 
    }, 
    copy: { 
     scripts: { 
      src: 'Scripts/**/**', 
      dest: 'build/' 
     } 
    }, 
    durandal: { 
     main: { 
      src: [ 
       'App/**/*.*', 
       '!App/main-built.js', // ignore the built file! 
       'Scripts/durandal/**/*.js' 
      ], 
      options: { 
       name: '../Scripts/almond-custom', 
       baseUrl: requireConfig.baseUrl, 
       mainPath: 'App/main', 
       paths: mixIn(
        {}, 
        requireConfig.paths, 
        { 'almond': '../Scripts/almond-custom.js' }), 
       exclude: [], 
       inlineText: false, // prevent bundling of .html (since we are dynamically generating these for content) 
       optimize: 'none', // turn off optimisations - uglify will run seperately by grunt to do this 
       out: 'build/app/main-built.js' 
      } 
     } 
    }, 
    uglify: { 
     options: { 
      banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> \n' + 
       '* Copyright (c) <%= grunt.template.today("yyyy") %> Kieran Benton \n' + 
       '*/\n' 
     }, 
     build: { 
      src: 'build/App/main.js', 
      dest: 'build/App/main-built.js' 
     } 
    } 
} 
); 

// loading plugin(s) 
grunt.loadNpmTasks('grunt-contrib-clean'); 
grunt.loadNpmTasks('grunt-contrib-connect'); 
grunt.loadNpmTasks('grunt-contrib-copy'); 
grunt.loadNpmTasks('grunt-contrib-jasmine'); 
grunt.loadNpmTasks('grunt-contrib-jshint'); 
grunt.loadNpmTasks('grunt-contrib-uglify'); 
grunt.loadNpmTasks('grunt-contrib-watch'); 
grunt.loadNpmTasks('grunt-open'); 
grunt.loadNpmTasks('grunt-durandal'); 

// only one grunt task 
grunt.registerTask('build', [ 
    'jshint', 
    'clean', 
    'copy', 
    'durandal:main']); 
}; 

Odpowiedz

10

Almond nie obsługuje dynamiczne ładowanie. Nie implementuje ona require.toUrl i nie obsługuje asynchronicznych wtyczek ładujących. James Burke, twórca RequireJS i Almond, odpowiedział na ten sam numer: here.

Aby obejść ten problem, można dołączyć RequireJS do pakietu zamiast Almond. Zobacz przykład here. Musisz utworzyć alias dla require.js w sekcji paths konfiguracji r.js, ponieważ require to specjalna zarezerwowana nazwa zależności. Następnie określ ten alias w polu name konfiguracji zamiast Almond. Dostaniesz coś takiego:

options: { 
    name: 'requireLib', // use the alias 
    baseUrl: requireConfig.baseUrl, 
    mainPath: 'App/main', 
    paths: mixIn(
     {}, 
     requireConfig.paths, 
     { 'requireLib': '../Scripts/require.js' }), // declare the alias 
    exclude: [], 
    inlineText: false, 
    optimize: 'none', 
    out: 'build/app/main-built.js' 
} 
+0

Czy istnieje sposób użycia r.js do zbudowania zoptymalizowanego pakietu, ale nadal zawierają pełną wersję wymaganego js (i nie migdałowy), który znasz? Nie jestem pewien, co mogę zrobić dalej ... –

+0

Cześć, Ciernie, też mam ten sam problem z tym, ale używam gulp-durandal. –

0

tylko dodać jakiś dodatkowy kontekst na to pytanie, ponieważ ja ciągle wracamy do niej orientacyjna i ostatecznie rozwiązać mój problem. Używam Durandal w/TypeScript i grunt do optymalizacji. Dostawałem wyjątki wokół wtyczki tekstowej, np.

<div data-bind="compose: { model: someObject, view: '../../components/something/something.html' }"></div>

skończyło się na usunięciu ścieżki względnej i tylko w następujący sposób:

<div data-bind="compose: { model: someObject, view: 'components/something/something.html' }"></div>

z tym, udało mi się dostać wszystko z zoptymalizowany proces budowania.

Powiązane problemy