前端技术不断更新, 自动化工具也在迭代, grunt在一些项目中依然会用到。接下来主要分享下用grunt如何使用babel, 能够直接在前端写 es6 语法, 特别是如何能够使用 es6 中模块化语法import, export。
如何配置grunt
配置grunt特别简单,一个Gruntfile.js 配置文件,安装相应的包。
具体参见grunt官网入门:http://www.gruntjs.net/getting-started
grunt能够完成哪些工作
grunt 主要通过插件完成前端自动化工作, 主要功能如下:
1. 文件合并 (grunt-contrib-concat)
2. 文件压缩 (js文件压缩,样式压缩)(grunt-contrib-uglify,grunt-contrib-cssmin)
3. 文件复制 (grunt-contrib-copy)
4. 文件清除 (grunt-contrib-clean)
5. 语法检查 (grunt-contrib-jshint)
6. es6转es5 (grunt-babel)
7. 起服务器 (grunt-contrib-connect)
8. 热加载 (connect-livereload)
9. 雪碧图 (grunt-css-sprite)
10. 单元测试 (grunt-karma)
可能遇到的问题
(1) 热加载功能需要和本地服务器一起使用,最细版本语法有更新, 如下demo
// 监听端口号
var lrPort = 6699;
// 生成脚本
var lrSnippet = require('connect-livereload')({ port: lrPort });
// 使用 middleware(中间件),就必须关闭 LiveReload 的浏览器插件
var serveStatic = require('serve-static');
var serveIndex = require('serve-index');
var lrMiddleware = function(connect, options, middlwares) {
return [
lrSnippet,
// 静态文件服务器的路径 原先写法:connect.static(options.base[0])
serveStatic(options.base[0]),
// 启用目录浏览(相当于IIS中的目录浏览) 原先写法:connect.directory(options.base[0])
serveIndex(options.base[0])
];
};
grunt.initConfig 中配置
connect: {
options: {
port: 9000,
host: 'localhost',
base: 'build'
},
livereload: {
options: {
open: true,
// 通过LiveReload脚本,让页面重新加载。
middleware: lrMiddleware
}
}
},
(2) 使用es6 的import语法,用babel转码后报错,exports undefined.
错误原因: es6 中的import,export 语法通过 bable转码后, 浏览器依然不认识。
解决方法: 安装浏览器识别的模块化umd插件,配置好babel; 并且先转码后再合并,压缩等操作。
- 安装amd模块化
npm install –save-dev babel-plugin-transform-es2015-modules-amd
- babel配置文件
{
"presets": [
["es2015"]
],
"plugins": [
"transform-es2015-modules-umd"
]
}
demo示例
- 目录结构:
- Gruntfile.js
/**
- @Desc: grunt 配置文件
- @Date: 2017-12-11
*/
// wrapper 函数
module.exports = function(grunt) {
// 监听端口号
var lrPort = 6699;
// 生成脚本
var lrSnippet = require('connect-livereload')({ port: lrPort });
// 使用 middleware(中间件),就必须关闭 LiveReload 的浏览器插件
var serveStatic = require('serve-static');
var serveIndex = require('serve-index');
var lrMiddleware = function(connect, options, middlwares) {
return [
lrSnippet,
// 静态文件服务器的路径 原先写法:connect.static(options.base[0])
serveStatic(options.base[0]),
// 启用目录浏览(相当于IIS中的目录浏览) 原先写法:connect.directory(options.base[0])
serveIndex(options.base[0])
];
};
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';'
},
basic: {
src: ['build/libs/*.js'],
dest: 'build/vendor.js'
},
// dist: {
// src: ['src/**/*.js', '!src/libs/*.js'],
// dest: 'build/<%= pkg.name %>.js'
// }
dist: {
src: ['build/**/*.js', '!build/vendor.js', '!build/libs/*.js'],
dest: 'build/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
files: {
'build/<%= pkg.name %>.min.js': ['build/<%= pkg.name %>.js'],
'build/vendor.min.js': ['build/vendor.js'],
}
// src: 'build/<%= pkg.name %>.js',
// dest: 'build/<%= pkg.name %>.min.js'
}
},
connect: {
options: {
port: 9000,
host: 'localhost',
base: 'build'
},
livereload: {
options: {
open: true,
// 通过LiveReload脚本,让页面重新加载。
middleware: lrMiddleware
}
}
},
copy: {
main: { expand: true, cwd: 'src', src: '**', dest: 'build/'}
},
clean: {
build: ['build/**']
},
watch: {
files: ['src/**', 'Gruntfile.js'],
options: {
livereload: lrPort
},
tasks: ['clean:build', 'concat', 'babel', 'uglify', 'copy:main']
},
babel: {
options: {
sourceMap: false,
presets: ['babel-preset-es2015']
},
dist: {
files: [{
expand: true,
cwd: '',
src: ['build/**/*.js', '!build/libs/*.js'],
dest: ''
}]
}
}
});
// 压缩
grunt.loadNpmTasks('grunt-contrib-uglify');
// 连接
grunt.loadNpmTasks('grunt-contrib-concat');
// 复制
grunt.loadNpmTasks('grunt-contrib-copy');
// 连接服务器
grunt.loadNpmTasks('grunt-contrib-connect');
// 清除
grunt.loadNpmTasks('grunt-contrib-clean');
// 监听文件
grunt.loadNpmTasks('grunt-contrib-watch');
// Babel
grunt.loadNpmTasks('grunt-babel');
grunt.registerTask('default', ['clean', 'copy', 'babel', 'concat', 'uglify', 'connect:livereload', 'watch']);
grunt.registerTask('test1', ['clean', 'concat', 'uglify', 'copy:main', 'connect:livereload', 'watch']);
};
a.js
export var aaa = "123456";
index.js
import { aaa } from './components/a.js';
console.log('aaa', aaa); //123456
结语
- grunt 是任务流的模式,我们可以清晰的知道前端自动化要做的事情;
- grunt 对vue, react支持不是很好, 没有解析.vue文件的插件, 此时用webpack等更适合;
- babel内容很多,推荐中文官网文档: https://babel.docschina.org/