Requirejs 使用r.js打包SPA应用程序,该应用程序使用';文本';

Requirejs 使用r.js打包SPA应用程序,该应用程序使用';文本';,requirejs,gruntjs,durandal,r.js,almond,Requirejs,Gruntjs,Durandal,R.js,Almond,我试图使用grunt将SPA应用程序(requirejs、durandal 2、knockout)构建到单个main-build.js文件中,而durandal用于加载我的视图的“文本”插件遇到了严重问题 在dev中,我成功地使用“文本”按照构建durandal应用程序的标准方式动态加载视图。不同之处在于我需要为视图做一些服务器端模板,因此它们实际上是动态生成的 考虑到这一点,我想使用r.js将应用程序模型、视图模型和服务(通过grunt durandal插件)打包到一个文件中,但不打包视图(.

我试图使用grunt将SPA应用程序(requirejs、durandal 2、knockout)构建到单个main-build.js文件中,而durandal用于加载我的视图的“文本”插件遇到了严重问题

在dev中,我成功地使用“文本”按照构建durandal应用程序的标准方式动态加载视图。不同之处在于我需要为视图做一些服务器端模板,因此它们实际上是动态生成的

考虑到这一点,我想使用r.js将应用程序模型、视图模型和服务(通过grunt durandal插件)打包到一个文件中,但不打包视图(.html)并根据需要动态加载它们

在我的grunt配置中,我使用了
inlineText:false
选项,我已经选中了该选项,它正在抑制“text!*”构建中的模块。但当我运行应用程序时,我得到:

Uncaught TypeError:undefined不是一个函数
从内部
文本。在下一行加载

var parsed = text.parseName(name),
            nonStripName = parsed.moduleName +
                (parsed.ext ? '.' + parsed.ext : ''),
            url = req.toUrl(nonStripName), // EXCEPTION THROWN HERE
正在加载的模块名称似乎是正确的(它是一个“text!*”名称),但除此之外,我不知道如何继续调试这个问题。我做错了什么

我的grunt配置是:

/*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']);
};
/*全局模块,需要*/
module.exports=函数(grunt){
"严格使用",;
//允许将配置对象合并在一起的库
var mixIn=require('mout/object/mixIn');
var RequireFig={
baseUrl:“App/”,
路径:{
“jquery”:“../Scripts/jquery-2.1.0”,
“敲除”:“../Scripts/knockout-3.1.0”,
“text”:“../Scripts/text”,
“durandal”:“../Scripts/durandal”,
“插件”:“../Scripts/durandal/plugins”,
“转换”:“../Scripts/durandal/transitions”,
}
};
grunt.initConfig({
pkg:grunt.file.readJSON('package.json'),
jshint:{
选项:{
“-W099”:true,//允许混合制表符和空格
“-W004”:true,//需要避免TS伪造继承的错误
忽略:[
'App/main build.js'//ingore生成/压缩文件
]
},
all:[//在这些文件上运行jshint
“gruntfile.js”,
“App/***.js”
]
},
//TODO:可以在这里添加jasmine来进行JS测试吗
清洁:{
内部版本:['build/*']
},
副本:{
脚本:{
src:'Scripts/***/**',
dest:'build/'
}
},
杜兰达尔:{
主要内容:{
src:[
“App/****”,
“!App/main build.js”,//忽略生成的文件!
'Scripts/durandal/***.js'
],
选项:{
名称:“../Scripts/almond custom”,
baseUrl:requireConfig.baseUrl,
主路径:“应用程序/主”,
路径:mixIn(
{},
需要配置路径,
{'almond':'../Scripts/almond custom.js'}),
不包括:[],
inlineText:false,//防止绑定.html(因为我们正在为内容动态生成这些文件)
优化:“无”//关闭优化-丑八怪将通过grunt单独运行来完成此操作
输出:“build/app/main build.js”
}
}
},
丑陋的:{
选项:{
横幅:'/*!\n'+
“*版权所有(c)Kieran Benton\n”+
“*/\n”
},
建造:{
src:'build/App/main.js',
dest:'build/App/main build.js'
}
}
}
);
//正在加载插件
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”);
//只有一项艰巨的任务
grunt.registerTask('build'[
“jshint”,
“干净”,
“复制”,
"durandal:main",;
};

Almond不支持动态加载。它不实现
require.toUrl
,也不支持异步加载程序插件。《安魂曲》和《杏仁》的创作者詹姆斯·伯克也回答了同样的问题

为了解决这个问题,您可以将RequireJS而不是Almond包含到包中。请看一个例子。由于
require
是一个特殊的保留依赖项名称,因此必须在r.js配置的
path
部分中为
require.js
创建别名。然后,在配置的
name
字段中指定此别名,而不是Almond。你会得到这样的结果:

选项:{
名称:'requireLib',//使用别名
baseUrl:requireConfig.baseUrl,
主路径:“应用程序/主”,
路径:mixIn(
{},
需要配置路径,
{'requireLib':'../Scripts/require.js'}),//声明别名
不包括:[],
inlineText:false,
优化:“无”,
输出:“build/app/main build.js”
}

我只是想为这个问题添加一些额外的背景知识,因为我一直在回来寻求指导,并最终解决了我的问题。我使用Durandal w/TypeScript和grunt进行优化。我在文本插件方面遇到了一些例外,例如


有没有一种方法可以使用r.js构建一个优化包,但仍然包含您所知道的require js(而不是almond)的完整版本?我不确定我下一步最好做什么…嗨,索恩,我也面临着同样的问题,但我正在使用gulp durandal。你能帮我解释/展示更多关于如何解决这个问题的细节吗?我对这件事很陌生。谢谢