0

0

什么是Grunt?对他的详细介绍

零下一度

零下一度

发布时间:2017-06-26 11:29:06

|

2285人浏览过

|

来源于php中文网

原创

前面的话

  前端技术的发展真的很快,15年还在流行grunt,而现在随着gulp的大量使用,以及webpack越来越流行,grunt基本上要被淘汰了。学习进度跟不上技术发展进度,实在是说不出的感觉。本文将介绍可能将过时的grunt

安装

  Grunt和Grunt插件是通过npm安装并管理的。在学习Grunt前,需要先将Grunt命令行(CLI)安装到全局环境中。安装时可能需要使用sudo(针对OSX、*nix、BSD等系统中)权限或者作为管理员(对于Windows环境)来执行以下命令

npm install -g grunt-cli

  上述命令执行完后,grunt命令就被加入到系统路径中了,以后就可以在任何目录下执行此命令了

  [注意]安装grunt-cli并不等于安装了Grunt。Grunt CLI的任务很简单:调用与Gruntfile在同一目录中的Grunt。这样带来的好处是,允许在同一个系统上同时安装多个版本的Grunt

  每次运行grunt时,就利用node提供的require()系统查找本地安装的Grunt。正是由于这一机制,可以在项目的任意子目录中运行grunt。如果找到一份本地安装的Grunt,CLI就将其加载,并传递Gruntfile中的配置信息,然后执行所指定的任务

 

配套

  一般需要在项目中添加两份文件:package.json 和 Gruntfile

  package.json: 此文件被npm用于存储项目的元数据,以便将此项目发布为npm模块。可以在此文件中列出项目依赖的grunt和Grunt插件,放置于devDependencies配置段内

  Gruntfile: 此文件被命名为 Gruntfile.js 或 Gruntfile.coffee,用来配置或定义任务(task)并加载Grunt插件

【package.json】

  package.json应当放置于项目的根目录中,与Gruntfile在同一目录中,并且应该与项目的源代码一起被提交。在上述目录(package.json所在目录)中运行npm install将依据package.json文件中所列出的每个依赖来自动安装适当版本的依赖

  常用的package.json配置如下

{  "name": "my-project-name",  "version": "0.1.0",  "devDependencies": {"grunt": "~0.4.5","grunt-contrib-jshint": "~0.10.0","grunt-contrib-nodeunit": "~0.4.1","grunt-contrib-uglify": "~0.5.0"
  }
}

  向已经存在的package.json 文件中添加Grunt和grunt插件的最简单方式是通过npm install <module> --save-dev</module>命令。此命令不光安装了<module></module>,还会自动将其添加到devDependencies 配置段中,如下所示

npm install grunt-contrib-jshint --save-dev

【Gruntfile】

  Gruntfile.js 或 Gruntfile.coffee 文件是有效的 JavaScript 或 CoffeeScript 文件,应当放在项目根目录中,和package.json文件在同一目录层级,并和项目源码一起加入源码管理器

  Gruntfile由以下几部分构成:

  • "wrapper" 函数

  • 项目与任务配置

  • 加载grunt插件和任务

  • 自定义任务

  在下面列出的这个 Gruntfile 中,package.json文件中的项目元数据(metadata)被导入到 Grunt 配置中, grunt-contrib-uglify 插件中的uglify 任务(task)被配置为压缩(minify)源码文件并依据上述元数据动态生成一个文件头注释。当在命令行中执行 grunt 命令时,uglify 任务将被默认执行

module.exports = function(grunt) {  // Project configuration.  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'  },
      build: {
        src: 'src/<%= pkg.name %>.js',
        dest: 'build/<%= pkg.name %>.min.js'  }
    }
  });  // 加载包含 "uglify" 任务的插件。
  grunt.loadNpmTasks('grunt-contrib-uglify');  // 默认被执行的任务列表。
  grunt.registerTask('default', ['uglify']);

};

  1、wrapper函数

  每一份 Gruntfile (和grunt插件)都遵循同样的格式,所书写的Grunt代码必须放在wrapper函数内

module.exports = function(grunt) {  // Do grunt-related things in here};

  2、项目和任务配置

  大部分的Grunt任务都依赖某些配置数据,这些数据被定义在一个object内,并传递给grunt.initConfig 方法

  Grunt的task配置都是在 Gruntfile 中的grunt.initConfig方法中指定的。此配置主要是以任务名称命名的属性,也可以包含其他任意数据。一旦这些代表任意数据的属性与任务所需要的属性相冲突,就将被忽略

grunt.initConfig({
  concat: {// 这里是concat任务的配置信息。  },
  uglify: {// 这里是uglify任务的配置信息  },  // 任意数据。
  my_property: 'whatever',
  my_src_files: ['foo/*.js', 'bar/*.js'],
});

  在一个任务配置中,options属性可以用来指定覆盖内置属性的默认值。此外,每一个目标(target)中还可以拥有一个专门针对此目标(target)的options属性。目标(target)级的平options将会覆盖任务级的options。options对象是可选的,如果不需要,可以忽略

grunt.initConfig({
  concat: {
    options: {      // 这里是任务级的Options,覆盖默认值     },
    foo: {
      options: {// "foo" target options may go here, overriding task-level options.      },
    },
    bar: {      // No options specified; this target will use task-level options.    },
  },
});

  在下面的案例中,grunt.file.readJSON('package.json') 将存储在package.json文件中的JSON元数据引入到grunt config中。 由于模板字符串可以引用任意的配置属性,因此可以通过这种方式来指定诸如文件路径和文件列表类型的配置数据,从而减少一些重复的工作

  与大多数task一样,grunt-contrib-uglify插件中的uglify 任务要求它的配置被指定在一个同名属性中。在这里有一个例子, 我们指定了一个banner选项(用于在文件顶部生成一个注释),紧接着是一个单一的名为build的uglify目标,用于将一个js文件压缩为一个目标文件

// Project configuration.grunt.initConfig({
  pkg: grunt.file.readJSON('package.json'),
  uglify: {
    options: {
      banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'},
    build: {
      src: 'src/<%= pkg.name %>.js',
      dest: 'build/<%= pkg.name %>.min.js'}
  }
});

  3、加载grunt插件和任务

  像 concatenation、[minification]、grunt-contrib-uglify 和 linting这些常用的任务(task)都已经以grunt插件的形式被开发出来了。只要在 package.json 文件中被列为dependency(依赖)的包,并通过npm install安装之后,都可以在Gruntfile中以简单命令的形式使用:

// 加载能够提供"uglify"任务的插件。grunt.loadNpmTasks('grunt-contrib-uglify');

  [注意] grunt --help 命令将列出所有可用的任务

  4、自定义任务

  通过定义 default 任务,可以让Grunt默认执行一个或多个任务。在下面的这个案例中,执行 grunt 命令时如果不指定一个任务的话,将会执行uglify任务。这和执行grunt uglify 或者 grunt default的效果一样。default任务列表数组中可以指定任意数目的任务(可以带参数)

// Default task(s).grunt.registerTask('default', ['uglify']);

 

合并

  本节将介绍合并插件grunt-contrib-concat的实例应用

  1、首先,建立项目结构。 根目录为'project',存在一个'src'的文件夹,该文件夹下又包含'css'和'js'这两个文件夹。其中,'css'文件夹有一个空的'concat'文件夹,一个'style1.css'文件,以及一个'style2.css'文件;类似地,'js'文件夹有一个空的'concat'文件夹,一个'script1.js'文件,以及一个'script2.js'文件

  由于需要用到grunt来实现合并,所以需要在项目根目录下,新建'package.json'和'Gruntfile.js'文件

  最终的目录结构如下所示

  2、填充文件内容

  合并的目的是把'style1.css'和'style2.css'的内容合并到'css/src/concat'文件夹下,把'script1.js'和'script2.js'的内容合并到'js/src/concat'文件夹下

  style1.css的文件内容如下

body{margin: 0;}

  style2.css的文件内容如下

ul{margin: 0;padding: 0;list-style:none;
}

  script1.js的文件内容如下

console.log('a');

  script2.js的文件内容如下

console.log('b');

  3、设置Grunt的package.json及Gruntfile.js文件

  由于需要用到grunt及grunt-contrib-concat插件,所以package.json的文件内容如下

{  "name": "project",  "version": "1.0.0",  "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1"
  }
}

  Gruntfile.js的配置文件如下

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {stripBanners: true,
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */'  },
      myCSSDist: {
        src: ['src/css/*.css'],
        dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css'  },
      myJSDist: {
        src: ['src/js/*.js'],
        dest: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js'  },      
    },
  });
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.registerTask('default', ['concat']);
};

  4、效果演示

  通过在命令行中使用npm install命令来安装插件

npm install

  然后执行命令grunt

闪拍cms竞拍系统
闪拍cms竞拍系统

竞拍程序针对一个商品进行竞拍,每个客户出价需要消耗一定量的金币,每次出价后倒计时会返回20秒,价格会加一点,这个都根据网站后台设置的,如果客户出价后,20内没有人出价,他就拍到商品了。对于网站运营着来说是采取的叠加方式收入的比如 1+2+3+4…… 具体详细玩法可见压缩包内详细例子介绍。

下载

  在'css/concat'文件夹下生成一个'project-1.0.0.css'的文件,内容如下

body{margin: 000-

  在'js/concat'文件夹下生成一个'project-1.0.0.js'的文件,内容如下

/*! project - v1.0.0 - 2017-05-27 */console.log('a');console.log('b');

 

压缩

  接下来,我们对合并后的project-1.0.0.css和project-1.0.0.js文件进行压缩,压缩名称加一个'.min'前缀,并分别保存到'project'目录下的'dist'目录下'css'文件夹和'js'文件夹

  由于需要用到grunt-contrib-cssmin和grunt-contrib-uglify插件,所以package.json的文件内容如下

{  "name": "project",  "version": "1.0.0",  "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1","grunt-contrib-cssmin": "^2.2.0","grunt-contrib-uglify": "^3.0.1"
  }
}

  Gruntfile.js的配置文件如下

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {
        stripBanners: true,
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */'  },
      myCSSDist: {
        src: ['src/css/*.css'],
        dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css'  },
      myJSDist: {
        src: ['src/js/*.js'],
        dest: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js'  },      
    },
    cssmin:{
      options: {
        stripBanners: true,
        banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */'        
      },
      build:{
        src: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css',
        dest: 'dist/css/<%= pkg.name %>-<%= pkg.version %>.min.css'        
      }

    },
    uglify:{
      options: {
        stripBanners: true,
        banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */'        
      },
      build:{
        src: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js',
        dest: 'dist/js/<%= pkg.name %>-<%= pkg.version %>.min.js'        
      }
    }
  });
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.registerTask('default', ['concat','cssmin','uglify']);
};

  通过在命令行中使用npm install命令来安装插件

  然后执行命令grunt

  在'dist/css/'文件夹下生成一个'project-1.0.0.min.css'的文件,内容如下

/*! project - v1.0.0 - 2017-05-27 */body{margin:0}ul{margin:0;padding:0;list-style:none}

  在'dist/js/'文件夹下生成一个'project-1.0.0.min.js'的文件,内容如下

/* 2017-05-27 */console.log("a"),console.log("b");

 

检查

  前面的博文已经介绍过jshint和csslint。如果要使用grunt中的插件,则需要在根目录下建立 .csslintrc 和 .jshintrc 文件,并设置它们的内容如下

//.csslintrc{"adjoining-classes":false,"box-sizing":false,"box-model":false,"compatible-vendor-prefixes": false,"floats":false,"font-sizes":false,"grandients":false,"important":false,"known-properties":false,"outline-none":false,"qualified-headings":false,"regex-selectors":false,"shorthand":false,"text-indent":false,"unique-headings":false,"universal-selector":false,"unqualified-attributes":false}//.jshintrc{"boss": false,"curly": true,"eqeqeq": true,"eqnull": true,"expr": true,"immed":true,"newcap":true,"noempty":true,"noarg":true,"undef":true,"regexp":true,"browser":false,"devel":true,"node":true}

  由于需要用到grunt-contrib-csslint和grunt-contrib-jshint插件,所以package.json的文件内容如下

{  "name": "project",  "version": "1.0.0",  "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1","grunt-contrib-cssmin": "^2.2.0","grunt-contrib-uglify": "^3.0.1","grunt-contrib-csslint": "^2.0.0","grunt-contrib-jshint": "^1.1.0"    
  }
}

  Gruntfile.js的配置文件如下

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {
        stripBanners: true,
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */'  },
      myCSSDist: {
        src: ['src/css/*.css'],
        dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css'  },
      myJSDist: {
        src: ['src/js/*.js'],
        dest: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js'  },      
    },
    cssmin:{
      options: {
        stripBanners: true,
        banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */'        
      },
      build:{
        src: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css',
        dest: 'dist/css/<%= pkg.name %>-<%= pkg.version %>.min.css'        
      }

    },
    uglify:{
      options: {
        stripBanners: true,
        banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */'        
      },
      build:{
        src: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js',
        dest: 'dist/js/<%= pkg.name %>-<%= pkg.version %>.min.js'        
      }
    },
    jshint:{
      options:{
        jshintrc:'.jshintrc'  },
      build:['Gruntfile.js','src/js/*.js']
    },
    csslint:{
      options:{
        csslintrc:'.csslintrc'  },
      build:['src/css/*.css']      
    }
  });
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.registerTask('default', ['jshint','csslint','concat','cssmin','uglify']);
};

  通过在命令行中使用npm install命令来安装插件

  然后执行命令grunt 

  可以看到'script1.js'文件中第1行缺少分号,修改后再执行命令grunt

 

监控

  grunt构建工具的自动化主要体现在grunt-contrib-watch插件上,该插件主要用于监听并执行对应的任务

  package.json的文件内容如下

{  "name": "project",  "version": "1.0.0",  "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1","grunt-contrib-csslint": "^2.0.0","grunt-contrib-cssmin": "^2.2.0","grunt-contrib-jshint": "^1.1.0","grunt-contrib-uglify": "^3.0.1","grunt-contrib-watch": "^1.0.0"
  }
}

  Gruntfile.js的配置文件如下

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {
        stripBanners: true,
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */'  },
      myCSSDist: {
        src: ['src/css/*.css'],
        dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css'  },
      myJSDist: {
        src: ['src/js/*.js'],
        dest: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js'  },      
    },
    cssmin:{
      options: {
        stripBanners: true,
        banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */'        
      },
      build:{
        src: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css',
        dest: 'dist/css/<%= pkg.name %>-<%= pkg.version %>.min.css'        
      }

    },
    uglify:{
      options: {
        stripBanners: true,
        banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */'        
      },
      build:{
        src: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js',
        dest: 'dist/js/<%= pkg.name %>-<%= pkg.version %>.min.js'        
      }
    },
    jshint:{
      options:{
        jshintrc:'.jshintrc'  },
      build:['Gruntfile.js','src/js/*.js']
    },
    csslint:{
      options:{
        csslintrc:'.csslintrc'  },
      build:['src/css/*.css']      
    },
    watch:{
      build:{
        files: ['src/js/*.js','src/css/*.css'],
        tasks: ['jshint','csslint','concat','cssmin','uglify'],
        options:{spawn:false}
      }
    }
  });
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.registerTask('default', ['jshint','csslint','concat','cssmin','uglify','watch']);
};

  通过在命令行中使用npm install命令来安装插件

  然后执行命令grunt

  修改'scrpt1.js'文件内容后,命令行自动显示如下

 

变动更新

  contrib-watch插件会监听需要处理的文件的变动,一旦有变动就会自动执行相应处理。但是它有一个问题,就是每当监听到一处变动时,就会大费周章地把所有被监听的文件都处理一遍

  而newer插件的作用是处理contrib-watch插件的毛病,让watch在监听到某个文件变动时,仅仅对变动的文件进行事务处理

  package.json的文件内容如下

{  "name": "project",  "version": "1.0.0",  "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1","grunt-contrib-csslint": "^2.0.0","grunt-contrib-cssmin": "^2.2.0","grunt-contrib-jshint": "^1.1.0","grunt-contrib-uglify": "^3.0.1","grunt-contrib-watch": "^1.0.0","grunt-contrib-requirejs": "^1.0.0","grunt-newer":"^1.3.0"
  }
}

  Gruntfile.js的配置文件如下

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {
        stripBanners: true,
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */'  },
      myCSSDist: {
        src: ['src/css/*.css'],
        dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css'  },
      myJSDist: {
        src: ['src/js/*.js'],
        dest: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js'  },      
    },
    cssmin:{
      options: {
        stripBanners: true,
        banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */'        
      },
      build:{
        src: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css',
        dest: 'dist/css/<%= pkg.name %>-<%= pkg.version %>.min.css'        
      }

    },
    uglify:{
      options: {
        stripBanners: true,
        banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */'        
      },
      build:{
        src: 'src/js/concat/<%= pkg.name %>-<%= pkg.version %>.js',
        dest: 'dist/js/<%= pkg.name %>-<%= pkg.version %>.min.js'        
      }
    },
    jshint:{
      options:{
        jshintrc:'.jshintrc'  },
      build:['Gruntfile.js','src/js/*.js']
    },
    csslint:{
      options:{
        csslintrc:'.csslintrc'  },
      build:['src/css/*.css']      
    },
    watch:{
      build:{
        files: ['src/js/*.js','src/css/*.css'],
        tasks: ['newer:jshint','newer:csslint','newer:concat','newer:cssmin','newer:uglify'],
        options:{spawn:false}
      }
    }
  });
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-newer');
  grunt.registerTask('default', ['newer:jshint','newer:csslint','newer:concat','newer:cssmin','newer:uglify','watch']);
};

  执行命令grunt

grunt

  由于'script1.js'的内容发生了变化,所以重新合并了js文件,project-1.0.0.min.js的内容如下

/* 2017-06-09 */console.log("a"),console.log("b");

  由于css的内容没有发生变化,所以project-1.0.0.min.css的内容如下

/*! project - v1.0.0 - 2017-05-29 */body{margin:0}ul{list-style:none;margin:0;padding:0}

 

模块化

  下面说明grunt如何与requireJS配合使用,需要使用contrib-requirejs插件

npm install grunt-contrib-requirejs

  该插件的使用与r.js的使用类似,不需要建立单独的build.js文件,而是在Gruntfile.js中配置

  设置如下项目结构,src为开发环境,dist为上线环境

  在r.js中,可以使用'dir'配置项,将项目目录复制到一个新的地方。但是,在实际项目开发中,有许多文件与requirejs无关,也会被复制。所以,不应该使用'dir',而应该使用'out'配置项,只是将入口文件main.js打包到一个新的地方

  一般地,jQuery并不打包到main.js文件中。如果使用相对路径,打包前的main.js(开发环境)与jQuery存在路径依赖关系。打包后的main.js已经处于新的环境(上线环境),但此时仍然与开发环境的jQuery存在路径依赖关系,不符合逻辑

  所以,jQuery应该是上线环境的地址。由于打包后,main.js的config也会打包进行,新的main.js的位置发生变化,jQuery的相对路径也会变化。所以config应该写在index.html页面中。这样,在jQuery或main.js的路径发生变化时,可以进行改动

  因此,script1.js和script2.js这两个文件的内容如下

//script.jsdefine(['jquery'],function (){return $('div').height();
})//s2.jsdefine(['jquery'],function (){return $('div').width();
})

  main.js的内容如下

//main.jsrequire(['module/script1','module/script2'], function(a,b){
  console.log(a);
  console.log(b);
});

   index.html代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div></div>
<script data-main="main" src="dist/js/require.js?1.1.11"></script>
<script>require.config({
    baseUrl:'src/js',
    paths:{'jquery':'../../dist/js/jquery'}
});</script>
</body>
</html>

  package.json的文件内容如下

{  "name": "project",  "version": "1.0.0",  "devDependencies": {"grunt": "^1.0.1","grunt-contrib-concat": "^1.0.1","grunt-contrib-csslint": "^2.0.0","grunt-contrib-cssmin": "^2.2.0","grunt-contrib-jshint": "^1.1.0","grunt-contrib-uglify": "^3.0.1","grunt-contrib-watch": "^1.0.0","grunt-contrib-requirejs": "^1.0.0","grunt-newer":"^1.3.0"
  }
}

【contrib-requirejs插件配置】

  由于该插件打包后的文件,内容还是使用原来的路径关系。但是,开发和线上的路径并不一致。所以,要把可能会变化的路径设置为'baseUrl',其他的路径保持一致

  [注意]contrib-requirejs插件不能与newer插件混用

    requirejs: {
      compile: {
        options: {
          baseUrl: 'src/js',
          paths:{
            jquery:'../../dist/js/jquery'  },
          name: 'main',       
          out:'dist/js/main.js',
          exclude: ['jquery']
        }
      }
    }

  Gruntfile.js的配置文件如下

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {
        stripBanners: true,
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +'<%= grunt.template.today("yyyy-mm-dd") %> */'  },
      myCSSDist: {
        src: ['src/css/*.css'],
        dest: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css'  }
    },
    cssmin:{
      options: {
        stripBanners: true,
        banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */'        
      },
      build:{
        src: 'src/css/concat/<%= pkg.name %>-<%= pkg.version %>.css',
        dest: 'dist/css/<%= pkg.name %>-<%= pkg.version %>.min.css'        
      }

    },
    jshint:{
      options:{
        jshintrc:'.jshintrc'  },
      build:['Gruntfile.js','src/js/*.js']
    },
    csslint:{
      options:{
        csslintrc:'.csslintrc'  },
      build:['src/css/*.css']      
    },
    requirejs: {
      compile: {
        options: {
          baseUrl: 'src/js',
          paths:{
            jquery:'../../dist/js/jquery'  },
          name: 'main',       
          out:'dist/js/main.js',
          exclude: ['jquery']
        }
      }
    },
    watch:{
      build:{
        files: ['src/js/*.js','src/css/*.css'],
        tasks: ['newer:jshint','newer:csslint','newer:concat','newer:cssmin','newer:uglify','requirejs'],
        options:{spawn:false}
      }
    }
  });
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-newer');

  grunt.registerTask('default', ['newer:jshint','newer:csslint','newer:concat','newer:cssmin','requirejs','watch']);
};

  执行命令grunt

  更改index.html页面如下,依然能正常显示

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><div></div><script data-main="main" src="dist/js/require.js?1.1.11"></script><script>require.config({
    baseUrl:'dist/js',
    paths:{'jquery':'../../dist/js/jquery'}
});</script></body></html>

 

 

相关文章

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

797

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

272

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

144

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

25

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

92

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

53

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

717

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

64

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号