# grunt

自动化,对于需要反复重复的任务,如压缩、编译、单元测试等,自动化工具可以减轻你的劳动,简化你的工作。当你在gruntfile文件正确配置好了任务,任务运行器会自动帮你完成大部分重复的工作。

最老牌的打包工具,它运用配置的思想来写打包脚本,一切皆配置。

优点:出现的比较早

缺点:

  • 配置项比较多
  • 不同的插件可能会有自己扩展的字段
  • 学习成本高,运用的时候需要明白各种插件的配置规则和配置方式

安装

cnpm i grunt grunt-babel @babel/core @babel/preset-env -D

Gruntfile.js

module.exports = function (grunt) {
  // 加载babel任务
  grunt.loadNpmTasks('grunt-babel')
  // 初始化配置文件
  grunt.initConfig({
    babel: {
      options: {
        sourceMap: true,
        presets: ['@babel/preset-env']
      },
      dist: {
        files: {
          'dist/app.js': 'src/app.js'
        }
      }
    }
  })
  // default指的是入口任务
  grunt.registerTask('default', ['babel'])
}

# gulp

基于node.js的stream流打包

定位是根据任务流的自动化构建工具

Gulp是通过task对整个开发过程进行构建

优点:

  • 流式的写法简单直观
  • API简单,代码量少
  • 易于学习和使用
  • 适合多页面应用开发

缺点:

  • 异常处理比较麻烦
  • 工作流程顺序难以精细控制
  • 不太适合单页面或自定义模块的开发
# 全局安装
cnpm install gulp-cli -g
# 项目中安装
cnpm install gulp gulp-babel @babel/core @babel/preset-env -D
# 创建配置文件
npx -p touch nodetouch gulpfile.js

gulpfile.js

const gulp = require('gulp')
const babel = require('gulp-babel')

function defaultTask(cb) {
  gulp
  .src('src/app.js') // 读取源文件
  .pipe(
    babel({ // 传给babel任务
      presets: ['@babel/preset-env']
    })
  )
  .pipe(gulp.dest('dist')) // 写入dist文件
  cb()
}

exports.default = defaultTask

# webpack

  • webpack是模块化管理工具和打包工具。通过loader的转换,任何形式的资源都可以视作模块儿。比如commonjs模块、AMD模块es6模块、CSS、图片儿等。它可以将许多松散的模块儿按照依赖和规则,打包成符合生产环境部署的前端资源。
  • 还可以将按需加载的模块进行代码分割,等到实际需要的时候再异步加载。
  • 它定位是模块打包器,而grunt/gulp属于构建工具。Webpack可以代替Gulp/grunt的一些功能,但不是一个职能的工具。可以配合使用。

优点:

  • 可以模块化的打包任何资源。
  • 适配任何模块儿的系统。
  • 适合spa单页应用的开发。 缺点:
  • 学习成本高,配置复杂。
  • 通过Babel编译后的js代码打包后体积过道。

安装

cnpm i webpack webpack-cli babel-loader @babel/preset-env @babel/core -D

webpack.config.js

const path = require('path')
module.exports = {
  mode: 'development',
  devtool: false,
  entry: './src/app.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        },
        include: path.join(__dirname, 'src'),
        exclude: /node_modules/
      }
    ]
  },
  plugins:[],
  devServer: {}
}

# rollup

  • rollup下一代es6模块打包工具,最大的亮点是利用es6模块设计,利用吹tree-shaking生成更简洁、更简单的代码。
  • 一般而言,对于应用使用Webpack,对于类库使用rollup
  • 需要代码拆分或者很多静态资源需要处理,再或者构建的项目需要引入很多CommonJS模块的依赖时,使用Web pack。
  • 代码库是基于es六模块,而且希望代码能够被他人直接使用,使用rollup。

优点:使用标准化的格式来写代码,通过减少死代码尽可能的缩小包体积。

缺点:对代码拆分、静态资源、CommonJS模块支持不好

cnpm i rollup rollup-plugin-node-resolve rollup-plugin-babel @babel/preset-env @babel/core -D 

rollup.config.js

import resolve from 'rollup-plugin-node-resolve'
import babel from 'rollup-plugin-babel'

export default {
  input: 'src/app.js',  // 这个包的入口点 
  output: {
    file: 'dist/bundle.js',
    format: 'cjs', // 指定生成包的格式,cjs – CommonJS,适用于 Node 和 Browserify/Webpack
    exports: 'default' // 使用什么导出模式。默认为auto,它根据entry模块导出的内容猜测你的意图,default – 如果你使用 export default ... 仅仅导出一个东西,那适合用这个
  },
  plugins: [
    resolve(),
    babel({
      'presets': ['@babel/preset-env'],
      exclude: 'node_modules/**' // 只编译我们的源代码
    })
  ]
}

上述配置项的详细含义可参考官方文档大选项列表 (opens new window)

src/app.js

const sum = (a, b) => a + b
export default sum

# parcel

  • parcel是快速、零配置的Web应用程序打包器
  • 目前parcel只能用来构建用于运行在浏览器中的网页,这也是它的出发点和关注点

优点:

  • parcel内置了常见场景的构建方案及其依赖,无需再安装各种依赖
  • parcel能以html为入口,自动检测和打包依赖资源
  • parcel默认支持模块热替换,真正的开箱即用

缺点:

  • 不支持sourcemap
  • 不支持剔除无效代码(TreeShaking)
  • 配置不灵活

安装

cnpm i parcel-bundler -D

package.json

{
  "name": "parcel",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "parcel src/index.html -p 8089",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "parcel-bundler": "^1.12.5"
  }
}