我现在正在构建一个项目,它将是一个webapp(浏览器可运行)和一个Phonegap应用程序(iOS和Android)。虽然我的项目理论上可以使用与 Yeoman 生成的{strong> Grunt 相同的dist
文件夹,{strong> {{3}} 任务build
通过运行grunt build
生成就绪代码。我希望运行类似grunt build_web
,grunt build_ios
和grunt build_android
的内容,以便为每个平台单独构建生产代码。或grunt build:web
,grunt build:ios
,grunt build:android
。这样,我可以使用自己的构建指令自定义一些加载的脚本,图像等。
那么,我是否应该通过我的Gruntfile以负责任的方式复制和粘贴所有(试过这个,没有用)dist
和build
指令?或者,是否有最好的做法?
Yeoman人,这可能吗?
以下是我当前的 Gruntfile.js ,以防万一有用。
'use strict';
var LIVERELOAD_PORT = 35729;
var lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT});
var mountFolder = function (connect, dir) {
return connect.static(require('path').resolve(dir));
};
// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'
module.exports = function (grunt) {
// show elapsed time at the end
require('time-grunt')(grunt);
// load all grunt tasks
require('load-grunt-tasks')(grunt);
// configurable paths
var yeomanConfig = {
app: 'app',
dist: '../www'
};
grunt.initConfig({
yeoman: yeomanConfig,
watch: {
coffee: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
tasks: ['coffee:dist']
},
coffeeTest: {
files: ['test/spec/{,*/}*.coffee'],
tasks: ['coffee:test']
},
compass: {
files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
tasks: ['compass:server', 'autoprefixer']
},
styles: {
files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
tasks: ['copy:styles', 'autoprefixer']
},
livereload: {
options: {
livereload: LIVERELOAD_PORT
},
files: [
'<%= yeoman.app %>/*.html',
'.tmp/styles/{,*/}*.css',
'{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
},
connect: {
options: {
port: 9000,
// change this to '0.0.0.0' to access the server from outside
hostname: 'localhost'
},
livereload: {
options: {
middleware: function (connect) {
return [
lrSnippet,
mountFolder(connect, '.tmp'),
mountFolder(connect, yeomanConfig.app)
];
}
}
},
test: {
options: {
middleware: function (connect) {
return [
mountFolder(connect, '.tmp'),
mountFolder(connect, 'test'),
mountFolder(connect, yeomanConfig.app)
];
}
}
},
dist: {
options: {
middleware: function (connect) {
return [
mountFolder(connect, yeomanConfig.dist)
];
}
}
}
},
open: {
server: {
path: 'http://localhost:<%= connect.options.port %>'
}
},
clean: {
options: {
force: true
},
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= yeoman.dist %>/*',
'!<%= yeoman.dist %>/.git*'
]
}]
},
server: '.tmp'
},
jshint: {
options: {
jshintrc: '.jshintrc'
},
all: [
'Gruntfile.js',
'<%= yeoman.app %>/scripts/{,*/}*.js',
'!<%= yeoman.app %>/scripts/vendor/*',
'test/spec/{,*/}*.js'
]
},
mocha: {
all: {
options: {
run: true,
urls: ['http://localhost:<%= connect.options.port %>/index.html']
}
}
},
coffee: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/scripts',
src: '{,*/}*.coffee',
dest: '.tmp/scripts',
ext: '.js'
}]
},
test: {
files: [{
expand: true,
cwd: 'test/spec',
src: '{,*/}*.coffee',
dest: '.tmp/spec',
ext: '.js'
}]
}
},
compass: {
options: {
sassDir: '<%= yeoman.app %>/styles',
cssDir: '.tmp/styles',
generatedImagesDir: '.tmp/images/generated',
imagesDir: '<%= yeoman.app %>/images',
javascriptsDir: '<%= yeoman.app %>/scripts',
fontsDir: '<%= yeoman.app %>/styles/fonts',
importPath: '<%= yeoman.app %>/bower_components',
httpImagesPath: '/images',
httpGeneratedImagesPath: '/images/generated',
httpFontsPath: '/styles/fonts',
relativeAssets: false
},
dist: {
options: {
generatedImagesDir: '<%= yeoman.dist %>/images/generated'
}
},
server: {
options: {
debugInfo: true
}
}
},
autoprefixer: {
options: {
browsers: ['last 1 version']
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
// not used since Uglify task does concat,
// but still available if needed
/*concat: {
dist: {}
},*/
requirejs: {
dist: {
// Options: https://github.com/jrburke/r.js/blob/master/build/example.build.js
options: {
// `name` and `out` is set by grunt-usemin
baseUrl: yeomanConfig.app + '/scripts',
optimize: 'none',
// TODO: Figure out how to make sourcemaps work with grunt-usemin
// https://github.com/yeoman/grunt-usemin/issues/30
//generateSourceMaps: true,
// required to support SourceMaps
// http://requirejs.org/docs/errors.html#sourcemapcomments
preserveLicenseComments: false,
useStrict: true,
wrap: true
//uglify2: {} // https://github.com/mishoo/UglifyJS2
}
}
},
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}',
'<%= yeoman.dist %>/styles/fonts/{,*/}*.*'
]
}
}
},
useminPrepare: {
options: {
dest: '<%= yeoman.dist %>'
},
html: '<%= yeoman.app %>/index.html'
},
usemin: {
options: {
dirs: ['<%= yeoman.dist %>']
},
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
},
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.{png,jpg,jpeg}',
dest: '<%= yeoman.dist %>/images'
}]
}
},
svgmin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.svg',
dest: '<%= yeoman.dist %>/images'
}]
}
},
cssmin: {
// This task is pre-configured if you do not wish to use Usemin
// blocks for your CSS. By default, the Usemin block from your
// `index.html` will take care of minification, e.g.
//
// <!-- build:css({.tmp,app}) styles/main.css -->
//
// dist: {
// files: {
// '<%= yeoman.dist %>/styles/main.css': [
// '.tmp/styles/{,*/}*.css',
// '<%= yeoman.app %>/styles/{,*/}*.css'
// ]
// }
// }
},
htmlmin: {
dist: {
options: {
/*removeCommentsFromCDATA: true,
// https://github.com/yeoman/grunt-usemin/issues/44
//collapseWhitespace: true,
collapseBooleanAttributes: true,
removeAttributeQuotes: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeOptionalTags: true*/
},
files: [{
expand: true,
cwd: '<%= yeoman.app %>',
src: '*.html',
dest: '<%= yeoman.dist %>'
}]
}
},
// Put files not handled in other tasks here
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'images/{,*/}*.{webp,gif}',
'styles/fonts/{,*/}*.*'
]
}]
},
styles: {
expand: true,
dot: true,
cwd: '<%= yeoman.app %>/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
},
modernizr: {
devFile: '<%= yeoman.app %>/bower_components/modernizr/modernizr.js',
outputFile: '<%= yeoman.dist %>/bower_components/modernizr/modernizr.js',
files: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
'!<%= yeoman.dist %>/scripts/vendor/*'
],
uglify: true
},
concurrent: {
server: [
'compass',
'coffee:dist',
'copy:styles'
],
test: [
'coffee',
'copy:styles'
],
dist: [
'coffee',
'compass',
'copy:styles',
'imagemin',
'svgmin',
'htmlmin'
]
},
bower: {
options: {
exclude: ['modernizr']
},
all: {
rjsConfig: '<%= yeoman.app %>/scripts/main.js'
}
}
});
grunt.registerTask('server', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'concurrent:server',
'autoprefixer',
'connect:livereload',
'open',
'watch'
]);
});
grunt.registerTask('test', [
'clean:server',
'concurrent:test',
'autoprefixer',
'connect:test',
'mocha'
]);
grunt.registerTask('build', [
'clean:dist',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'requirejs',
'concat',
'cssmin',
'uglify',
'modernizr',
'copy:dist',
'rev',
'usemin'
]);
grunt.registerTask('default', [
'jshint',
'test',
'build'
]);
};
答案 0 :(得分:3)
除了为PG 3推荐的内容之外,没有最佳实践。对于多个客户端,您可能想要修改您的gruntjs。这是我的项目结构,其中assets文件夹包含不同客户端的数据:
这是我的gruntjs文件。它使用ImageMagik创建所有必要的启动器图标。构建和部署无线安装。你明白了......
/***
* Package script for MobileStore
***/
'use strict';
// require package.json:
/*
{
"name": "MobileStore",
"version": "1.0.1",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.6.0",
"grunt-contrib-clean": "~0.4.1",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-concat": "~0.3.0",
"grunt-exec": "~0.4.2",
"grunt-string-replace": "~0.2.4",
"grunt-image-resize": "~0.2.0"
}
}
*/
module.exports = function(grunt) {
var isMacOS = grunt.file.isDir('/etc');
// load all grunt tasks
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
// configurable paths
var myConfig = {
dest: 'out/',
platforms: ['ios', 'android'],
chains: [11,52,75,119,129,224,229,235],
chainConfig: {},
baseDir: __dirname + '/'
};
var chainid = grunt.option('chainid');
if (chainid) {
myConfig.chains = [chainid];
}
// set up grunt
var gruntConfig = {
clean: {
build: ['out', 'beta-assets']
},
copy: {},
exec: {},
"string-replace": {},
image_resize: {}
};
// first thing to do is clean
var packageConfig = ['clean'];
// duplicate source to the chain
// copy from platforms/(android/ios) to out/chainid/(android/ios)
myConfig.chains.forEach(function(chain) {
myConfig.platforms.forEach(function(platform) {
var key = 'setup_' + platform + chain;
// any platform is fine, we're just preping chainConfig
if (platform == 'android')
{
myConfig.chainConfig[chain] = require('./YourCompany.Mobile/assets/' + chain + '/build.json');
}
gruntConfig.copy[key] = {
files: [
{
expand: true,
cwd: 'YourCompany.Mobile/platforms/' + platform + '/',
src: ['./**'],
dest: 'out/' + chain + '/' + platform + '/'
}
]
};
packageConfig.push('copy:' + key);
});
});
// override the device resource (icon, splash, etc..)
// copy from assets/chainid/device/(android/ios) to out/chainid/(android/ios)
myConfig.chains.forEach(function(chain) {
myConfig.platforms.forEach(function(platform) {
var key = 'device_resource_' + platform + chain;
var srcArt = 'YourCompany.Mobile/assets/' + chain + '/device/AndroidArtwork.png';
var dest = 'out/' + chain + '/' + platform + '/MobileStore/';
if (platform == 'android')
{
dest += 'res/';
}
else if (platform == 'ios') {
dest += 'MobileStore/';
}
gruntConfig.copy[key] = {
files: [
{
expand: true,
cwd: 'YourCompany.Mobile/assets/' + chain + '/device/' + platform + '/',
src: ['./**'],
dest: dest
}
]
};
packageConfig.push('copy:' + key);
// do image manipulations
// Use AnroidArtwork.png
if (platform == 'android') {
gruntConfig.image_resize[key + '_36'] = {
options: {
width: 36,
height: 36,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'drawable-ldpi/icon.png'
}]
};
packageConfig.push('image_resize:' + key + '_36');
gruntConfig.image_resize[key + '_48'] = {
options: {
width: 48,
height: 48,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'drawable-mdpi/icon.png'
}]
};
packageConfig.push('image_resize:' + key + '_48');
gruntConfig.image_resize[key + '_72'] = {
options: {
width: 72,
height: 72,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'drawable-hdpi/icon.png'
}]
};
packageConfig.push('image_resize:' + key + '_72');
gruntConfig.image_resize[key + '_96'] = {
options: {
width: 96,
height: 96,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'drawable-xhdpi/icon.png'
}]
};
packageConfig.push('image_resize:' + key + '_96');
gruntConfig.image_resize[key + '_default'] = {
options: {
width: 96,
height: 96,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'drawable/icon.png'
}]
};
packageConfig.push('image_resize:' + key + '_default');
}
else if (platform == 'ios') {
gruntConfig.image_resize[key + '_57'] = {
options: {
width: 57,
height: 57,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'Resources/icons/Icon.png'
}]
};
packageConfig.push('image_resize:' + key + '_57');
gruntConfig.image_resize[key + '_114'] = {
options: {
width: 114,
height: 114,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'Resources/icons/Icon@2x.png'
}]
};
packageConfig.push('image_resize:' + key + '_114');
gruntConfig.image_resize[key + '_72'] = {
options: {
width: 72,
height: 72,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'Resources/icons/Icon-72.png'
}]
};
packageConfig.push('image_resize:' + key + '_72');
gruntConfig.image_resize[key + '_144'] = {
options: {
width: 144,
height: 144,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'Resources/icons/Icon-72@2x.png'
}]
};
packageConfig.push('image_resize:' + key + '_144');
gruntConfig.image_resize[key + '_29'] = {
options: {
width: 29,
height: 29,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'Resources/icons/Icon-Small.png'
}]
};
packageConfig.push('image_resize:' + key + '_29');
gruntConfig.image_resize[key + '_58'] = {
options: {
width: 58,
height: 58,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'Resources/icons/Icon-Small@2x.png'
}]
};
packageConfig.push('image_resize:' + key + '_58');
gruntConfig.image_resize[key + '_50'] = {
options: {
width: 50,
height: 50,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'Resources/icons/Icon-Small-50.png'
}]
};
packageConfig.push('image_resize:' + key + '_50');
gruntConfig.image_resize[key + '_100'] = {
options: {
width: 100,
height: 100,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + 'Resources/icons/Icon-Small-50@2x.png'
}]
};
packageConfig.push('image_resize:' + key + '_100');
gruntConfig.image_resize[key + '_1024'] = {
options: {
width: 1024,
height: 1024,
overwrite: true,
upscale: true
},
files: [{
src: srcArt,
dest: dest + 'Resources/iTunesArtwork'
}]
};
packageConfig.push('image_resize:' + key + '_1024');
// setup images for ota deploy
gruntConfig.image_resize[key + '_512x'] = {
options: {
width: 512,
height: 512,
overwrite: true,
upscale: true
},
files: [{
src: srcArt,
dest: dest + '../iTunesArtwork.png'
}]
};
packageConfig.push('image_resize:' + key + '_512x');
gruntConfig.image_resize[key + '_57x'] = {
options: {
width: 57,
height: 57,
overwrite: true
},
files: [{
src: srcArt,
dest: dest + '../Icon.png'
}]
};
packageConfig.push('image_resize:' + key + '_57x');
}
});
});
// copy assets to www folder
// copy from www to out/chainid/...
myConfig.chains.forEach(function(chain) {
myConfig.platforms.forEach(function(platform) {
var key = 'content_' + platform + chain;
var dest = 'out/' + chain + '/' + platform + '/MobileStore/';
if (platform == 'android')
{
dest += 'assets/www/';
}
else if (platform == 'ios') {
dest += 'www/';
}
gruntConfig.copy[key] = {
files: [
{
expand: true,
cwd: 'YourCompany.Mobile/www/',
src: ['./**'],
dest: dest
}
]
};
packageConfig.push('copy:' + key);
});
});
// copy assets override
// copy from assets/chainid/www to out/chainid/...
myConfig.chains.forEach(function(chain) {
myConfig.platforms.forEach(function(platform) {
var key = 'content_override_' + platform + chain;
var dest = 'out/' + chain + '/' + platform + '/MobileStore/';
if (platform == 'android')
{
dest += 'assets/www/';
}
else if (platform == 'ios') {
dest += 'www/';
}
gruntConfig.copy[key] = {
files: [
{
expand: true,
cwd: 'YourCompany.Mobile/assets/' + chain + '/www/',
src: ['./**'],
dest: dest
}
]
};
packageConfig.push('copy:' + key);
});
});
// copy phonegap merges
// copy from merges to out/chainid/...
myConfig.chains.forEach(function(chain) {
myConfig.platforms.forEach(function(platform) {
var key = 'phonegap_override_' + platform + chain;
var dest = 'out/' + chain + '/' + platform + '/MobileStore/';
if (platform == 'android')
{
dest += 'assets/www/';
}
else if (platform == 'ios') {
dest += 'www/';
}
gruntConfig.copy[key] = {
files: [
{
expand: true,
cwd: 'YourCompany.Mobile/merges/' + platform,
src: ['./**'],
dest: dest
}
]
};
packageConfig.push('copy:' + key);
});
});
// doing beta assets deployment
myConfig.chains.forEach(function (chain) {
var key = 'content_beta_assets_' + chain;
var src = 'out/' + chain + '/ios/MobileStore/www/';
gruntConfig.copy[key] = {
files: [
{
expand: true,
cwd: src,
src: ['./**'],
dest: 'beta-assets/' + chain + '/www/'
}
]
};
packageConfig.push('copy:' + key);
// override cordova file
gruntConfig.copy[key + '_pg'] = {
files: [
{
expand: true,
cwd: 'YourCompany.Mobile/www/',
src: ['./cordova.js'],
dest: 'beta-assets/' + chain + '/www/'
}
]
};
packageConfig.push('copy:' + key + '_pg');
});
// doing android(ant) build
myConfig.chains.forEach(function (chain) {
var key = 'android_build_' + chain;
var dest = 'out/' + chain + '/android/MobileStore/';
var destFolder = './out/' + chain + '/';
// use previous chainConfig to perform text replace
gruntConfig["string-replace"][key + '_prep'] = {
files: [
{
expand: true,
cwd: 'out/' + chain + '/',
src: ['./**/**.java', './**/**.xml', './**/**.plist', './**/**.m'],
dest: 'out/' + chain + '/'
}
],
options: {
replacements: [
{
pattern: /(net.yourcompany.MobileStore)+/ig,
replacement: myConfig.chainConfig[chain].id
},
{
pattern: /(AppleBundleSeedID)+/ig,
replacement: myConfig.chainConfig[chain].AppleBundleSeedID
},
{ pattern: '<string name="app_name">MobileStore</string>',
replacement: '<string name="app_name">' + myConfig.chainConfig[chain].ApplicationName + '</string>'
}
]
}
};
packageConfig.push('string-replace:' + key + '_prep');
// do build
gruntConfig.exec[key] = {
cmd: 'ant clean && ant debug',
cwd: dest,
env: process.env
};
packageConfig.push('exec:' + key);
});
// doing xcode build
myConfig.chains.forEach(function(chain) {
var key = 'ios_build_' + chain;
var chainConfig = myConfig.chainConfig[chain];
var dest = myConfig.baseDir + 'out/' + chain + '/ios/MobileStore/';
var buildDir = dest + 'Build/Products/Release-iphoneos/';
var commandStart = 'export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/opt/local/bin:/opt/local/sbin:/sbin:/usr/local/bin:/Users/Shared/ImageMagick-6.8.6:$PATH" &&'
var command = 'chmod 777 dobuild && ./dobuild "' + chainConfig.AppleProductName + '" ' + chain + ' ' + process.env.BUILD_NUMBER + ' "' + chainConfig.AppleBundleSeedID + '.' + chainConfig.id + '"';
grunt.log.debug('ios build:' + command);
if (isMacOS) {
gruntConfig.exec[key] = {
cmd: command,
cwd: dest,
exitCode: 0
};
packageConfig.push('exec:' + key);
}
// prep apk for deployment
gruntConfig.copy['android_build_' + chain + '_apk'] = {
options: {
processContent: false
},
files: [
{
expand: true,
flatten: true,
src: ['out/' + chain + '/android/MobileStore/bin/MobileStore-debug.apk'],
dest: 'beta-assets/' + chain + '/',
filter: 'isFile'
}
]
};
packageConfig.push('copy:' + 'android_build_' + chain + '_apk');
// prep ipa for ios deploy
gruntConfig.copy['ios_build_' + chain + '_ipa'] = {
options: {
processContent: false
},
files: [
{
expand: true,
flatten: true,
src: ['out/' + chain + '/ios/MobileStore/Build/**.ipa'],
dest: 'beta-assets/' + chain + '/',
filter: 'isFile'
}
]
};
packageConfig.push('copy:' + 'ios_build_' + chain + '_ipa');
// drop plist
gruntConfig.copy['ios_build_' + chain + '_plist'] = {
options: {
processContent: false
},
files: [
{
expand: true,
flatten: true,
src: ['out/' + chain + '/ios/MobileStore/Build/**.plist'],
dest: 'beta-assets/' + chain + '/',
filter: 'isFile'
}
]
};
packageConfig.push('copy:' + 'ios_build_' + chain + '_plist');
// drop html
gruntConfig.copy['ios_build_' + chain + '_html'] = {
options: {
processContent: false
},
files: [
{
expand: true,
flatten: true,
src: ['out/' + chain + '/ios/MobileStore/Build/install.html'],
dest: 'beta-assets/' + chain + '/',
filter: 'isFile'
}
]
};
packageConfig.push('copy:' + 'ios_build_' + chain + '_html');
// drop png
gruntConfig.copy['ios_build_' + chain + '_png'] = {
options: {
processContent: false
},
files: [
{
expand: true,
flatten: true,
src: ['out/' + chain + '/ios/MobileStore/*.png'],
dest: 'beta-assets/' + chain + '/',
filter: 'isFile'
}
]
};
packageConfig.push('copy:' + 'ios_build_' + chain + '_png');
});
grunt.initConfig(gruntConfig);
grunt.registerTask('package', packageConfig);
// Default task.
grunt.registerTask('default', 'package');
};
基本上,它会删除所有本机并合并到out / clientorchainid文件夹中,以便为每个客户端进行构建。然后将构建结果复制到beta-assets / clientorchainid文件夹中,为远程部署做准备。
答案 1 :(得分:2)
Build是其他任务的列表。你可以这样做(coffeescript):
grunt.registerTask "build", [
"clean:dist",
"jade:html",
"clientTemplates",
"useminPrepare",
"concurrent:dist",
"copy:prerequire",
"requirejs",
"cssmin",
"concat",
"uglify",
"copy:dist",
"rev",
"usemin"
]
这样您就可以定义自定义任务和自定义构建等。