从weyland.js迁移到grunt.js的Durandal项目构建报错如何解决
错误根因
你遇到的Cannot read property 'normalize' of undefined报错核心是Grunt配置与原weyland的rjs构建规则不匹配,缺失了text插件处理、模块占位等必须配置,导致requirejs构建时无法正确处理html模板资源。
配置修正点
你当前的配置存在3个核心问题:
- 缺失
stubModules: ['text']、insertRequire: ['main']、wrap: true等原weyland配置中的必须项 - 原配置中jquery、knockout、bootstrap设置为
empty:(不打包进构建产物,复用页面全局引入的版本),但Grunt配置中改为了实际文件路径,会导致重复加载冲突 - 未配置html后缀与text插件的映射规则,rjs无法识别html模板资源
修正后的Gruntfile配置
module.exports = function (grunt) { grunt.initConfig({ jshint: { all: 'App/**/*.js' }, durandal: { main: { src: [ 'App/**/*.js', 'App/**/*.html', 'Scripts/durandal/**/*.js' ], options: { name: '../Scripts/almond-custom', baseUrl: './App/', mainPath: 'App/main', // 对齐原weyland配置的必须项 insertRequire: ['main'], wrap: true, loaderPluginExtensionMaps: { '.html': 'text' }, paths: { 'text': '../Scripts/text', 'durandal': '../Scripts/durandal', 'plugins': '../Scripts/durandal/plugins', 'transitions': '../Scripts/durandal/transitions', // 和原配置对齐,不打包公共依赖 'knockout': 'empty:', 'bootstrap': 'empty:', 'jquery': 'empty:' }, inlineText: true, optimize: 'none', pragmas: { build: true }, stubModules: ['text'], out: 'App/main-built.js' } } }, uglify: { build: { src: 'App/main-built.js', dest: 'App/main-built.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-durandal'); // 对齐原weyland的构建流程 grunt.registerTask('default', ['jshint', 'durandal', 'uglify']); };
验证注意事项
- 确认
Scripts目录下存在almond-custom.js、text.js两个依赖文件,路径与配置完全匹配 - 若需要将jquery、knockout打包进构建产物,将对应路径改为实际文件路径、删除
empty:配置即可,同时要删除页面中对应的script引入标签,避免重复加载报错 - 若要完全对齐原weyland先压缩零散JS再合并的逻辑,可拆分uglify任务为两步:第一步先压缩所有
App/**/*.js和Scripts/durandal/**/*.js文件,再执行durandal合并,最后再做一次全局压缩即可
内容的提问来源于stack exchange,提问作者magro
相关产品推荐
相关产品推荐

