前端构建系统

  • 用 npm 脚本简化复杂的命令
  • 用 Gulp 管理重复性任务
  • 用 Webpack 打包客户端 Web 程序

用 npm 运行脚本

  • 创建定制的 npm 脚本
  1. npm run script-name 可以运行任何(定制)脚本。

  2. 以 babel、uglify-es 为例:

    {
    	//...
    	"scripts": {
    	"babel": "./node_modules/.bin/babel index.js -d build/",
    	"uglify": "./node_modules/.bin/uglifyjs build/index.js -o build/index.min.js",
    	"build": "npm run babel && npm run uglify"
    }
    
  3. 运行 npm run build 会执行那两个脚本。这是因为 Babel 和 UglifyJS 都可以作为命令行脚本执行,并且都接受命令行参数,用这个简单的命令可以组合多个前端打包工具。

三种配置前端构建工具的方法:命令行参数、单独的配置文件、配置参数添加到 package.json 中

问题也随之显现......随着构建工具的增多,我们不可能像上述这样一个个地给每个工具写配置、配参数,所以我们寻求一个自动化构建的解决方案。

用 Gulp 实现自动化构建

  • Gulp 是基于流的构建系统。
  • 通过对这些流的引导来创建构建过程,除了转译和缩码,还能做很多事情。
  • Gulp 之所以能实现高度重用,主要归功于两项技术:使用插件和自定义构建任务。
  • Gulp 任务的创建及运行如下
// 打开gulpfile.js设置一个构建任务,用gulp.src查找JSX文件,用Babel处理ES2015和React,然后把这些文件拼到一起。
// 使用:在终端里输入gulp就可以运行这个Gulp任务。

// gulpfile.js 代码如下:
const  gulp = require('gulp');
const  sourcemaps = require('gulp-sourcemaps'); ←---- 像加载标准Node模块那样加载Gulp  插件
const  babel = require('gulp-babel');
const  concat = require('gulp-concat');
gulp.task('default', () => {
	return  gulp.src('app/*.jsx') ←---- 用Gulp自带的文件聚集工具gulp.src查找所有的React jsx文件
			.pipe(sourcemaps.init()) ←---- 开始监视源文件,为调试构建源码映射
			.pipe(babel({ presets: ['es2015', 'react']})
			.pipe(concat('all.js')) ←---- 把所有源码文件拼到一个all.js中
			.pipe(sourcemaps.write('.')) ←---- 单独写入源码映射文件
			.pipe(gulp.dest('dist')); ←---- 将所有文件放到dist/目录下
});

根据以上代码示例总结出,在 Gulp 中,一般构建流程为:

  • Gulp 监测变化 —— 构建/刷新循环
// gulp-watch插件 监测文件系统的变化
// npm i --save-dev gulp-watch

const  watch = require('gulp-watch')
gulp.task('watch', () => {
	watch('app/**.jsx', () =>  gulp.start('default'))
})

// 监测React JSX文件的变化。只要有文件发生了变化,默认的构建任务 gulp.start('default') 就会运行。
  • 项目规模变大后,Gulp 任务的组织方式:

    • gulp/

      • tasks/

        • task1.js
        • task2.js
      • gulp/

        • index.js ← 加载所有的 Gulp 任务文件
    • gulpfile.js ← 引入这个 gulp/index.js 文件

用 Webpack 构建 Web 程序 - 新一代构建工具(较 Gulp)

  • 二者区别:用 Gulp 时,写 JavaScript 代码是为了驱动构建系统,所以会涉及写 gulpfile 和构建任务。而用 Webpack 时,写的是配置文件,用插件和加载器添加新功能。
  • webpack 插件与加载器
  • 插件:用来改变构建过程的行为,比如静态资源自动上传、文件去重等。
  • 加载器:是函数,负责将输入的源文本转换为特定的文本输出, 比如转换 React 代码、CoffeeScript、SASS 或其他转译语言。
  • 一个 webpack.config.js 文件
const  path = require('path');
const  webpack = require('webpack');

module.exports = {
	entry:  './app/index.jsx', ←---- 输入文件
	output: { path:  __dirname, filename:  'dist/bundle.js' }, ←---- 输出文件
	module: {
		loaders: [
			{
				test: /.jsx?$/, ←---- 匹配所有的JSX文件
				loader:  'babel-loader',
				exclude: /node_modules/,
				query: {
					presets: ['es2015', 'react'] ←---- 使用Babel  ES2015和React  插件
                    // ....
				}
			}
		] // loaders config
	} // module config
};
    • webpack_require
    • module.exports
  • Webpack 把 CommonJS 模块给了我们,无须任何额外的配置,就可以使用来自 npm 的模块。