分享

工程化实践:自动化构建与打包

 汉无为 2023-08-26 发布于湖北













前言














前端项目越来越复杂,代码量越来越庞大,为了提高开发效率和代码质量,前端工程化势在必行。而自动化构建和部署是工程化中重要一环。借助自动化构建工具可有效地处理繁琐、重复而有意义的事,比如文件打包、压缩合并、语言编译、资源优化等,而自动化部署工具能帮助我们把构建后的文件快速、简单地部署到服务器。这些工具的使用,让开发人员专注于业务功能实现,让前端工程化变得更简单、高效。












工具选型














构建工具从早期基于流的gulp,到基于静态模块构建的webpack,再到当下炙手可热的Vite。经历多个工具的演变,一直在追求构建更极致的性能和体验,也让构建流程变得更完善和简单,下面将从各个工具的社区活跃度、基本使用、优缺点等维度简单介绍

技术

Star

Fork

备注

webpack

63.3k

8.8k

基于静态模块的构建工具

Vite

58k

5.2k

Vue开发团队尤雨溪研发

gulp

32.8k

4.4k

基于流的自动化构建工具

Grunt

12.2k

1.5k

基于任务的构建工具

Fis3

2.8k

717

百度研发的国产构建工具

webpack

基于Node.js开发的前端项目自动化构建工具,可以完美地实现前端资源的合并、打包、压缩、混淆、分割等诸多功能。本质上,webpack是一个用于现代JavaScript应用程序的静态模块打包工具,当webpack处理应用程序时,它会在内部从一个或多个入口构建一个依赖图,然后将项目中所需的每一个模块组合成一个或多个bundles,它们均为静态资源,用于展示你的内容。

图片

使用示例:
module.exports = {
  // 所有模块的入口,Webpack 从入口开始递归解析出所有依赖的模块
  entry: './app.js',
  output: {
    // 把入口所依赖的所有模块打包成一个文件 bundle.js 输出
    filename: 'bundle.js'
  }
}
官网:https://www.
优点:
  • 专注于处理模块化的项目以及项目中模块之间的依赖关系,能做到开箱即用一步到位;
  • 通过Plugin扩展,功能完整好用又不失灵活;
  • 使用场景不仅限于web开发;
  • 社区庞大活跃度高,经常引入紧跟行业发展的新特性,丰富的开源扩展;
  • 良好的开发体验

缺点:

  • 只能用于模块化开发的项目
  • 只能处理静态模块内容,无法处理动态内容

Vite

图片

定位为下一代前端开发与构建工具,利用生态系统中的新进展(如浏览器开始原生支持ES模块,越来越多JavaScript工具使用编译型语言编写)解决大型应用开发过程中的性能瓶颈:通过需要很多时间才能启动开发服务器,即使使用模块热替换(HMR),文件修改后的效果也需要几秒才能在浏览器体现出来,如何循环往复,迟钝的反馈会极大影响开发者的开发效率和幸福感。
使用示例:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'
import viteCompression from 'vite-plugin-compression'

// https://v/config/
export default defineConfig({
  plugins: [
      vue(),
      viteCompression({
        deleteOriginFile: false,
        algorithm: 'gzip',
        ext: '.gz',
      })
  ],
  resolve: {
    alias: {
      '@' : fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  base: './',
  //关键代码
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
      }
    }
  }
})
官网:https://
优点:
  • 极速的服务启动。使用原生ESM文件,无需打包;
  • 轻量快速的热重载。无论应用程序大小如何,都始终极快的模块热替换(HMR);
  • 丰富的功能。对TypeScript、JSX、CSS等支持开箱即用;
  • 优化的构建。可选“多页应用”或“库”模式的预配置Rollup构建;
  • 通用的插件。开发和构建之间共享Rollup-superset插件接口;
  • 完全类型化的API。灵活的API和完善的TypeScript类型;

gulp

图片

gulp是一个基于流的自动化构建工具。除了可以管理和执行任务,还支持监听文件、读写文件。gulp设计得非常简单,只通过下面5个方法可以胜任几乎所有的构建场景
  1. 通过gulp.task注册一个任务
  2. 通过gulp.run执行任务
  3. 通过gulp.watch监听文件变化
  4. 通过gulp.src读取文件
  5. 通过gulp.dest写文件

使用示例大概如下
// 引入 Gulp
var gulp = require('gulp');
// 引入插件
var jshint = require('gulp-jshint');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
 
// 编译 SCSS 任务
gulp.task('sass', function() {
  // 读取文件通过管道喂给插件
  gulp.src('./scss/*.scss')
    // SCSS 插件把 scss 文件编译成 CSS 文件
    .pipe(sass())
    // 输出文件
    .pipe(gulp.dest('./css'));
});
 
// 合并压缩 JS
gulp.task('scripts', function() {
  gulp.src('./js/*.js')
    .pipe(concat('all.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./dist'));
});
 
// 监听文件变化
gulp.task('watch', function(){
  // 当 scss 文件被编辑时执行 SCSS 任务
  gulp.watch('./scss/*.scss', ['sass']);
  gulp.watch('./js/*.js', ['scripts']);
});

官网:https://www.

优点:好用又不失灵活,即可以单独完成构建也可以和其他工具搭配使用

缺点:集成度不高,要写很多匹配后才可以使用,无法开箱即用

Grunt

图片

Grunt是一个任务执行者。有大量现成的插件封装了常见的任务,也能管理任务之间的依赖关系,自动化执行依赖的任务,每个任务的具体执行代码和依赖关系写在配置文件Gruntfile.js里,例如:
module.exports = function(grunt) {
  // 所有插件的配置信息
  grunt.initConfig({
    // uglify 插件的配置信息
    uglify: {
      app_task: {
        files: {
          'build/app.min.js': ['lib/index.js', 'lib/test.js']
        }
      }
    },
    // watch 插件的配置信息
    watch: {
      another: {
          files: ['lib/*.js'],
      }
    }
  });
 
  // 告诉 grunt 我们将使用这些插件
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
 
  // 告诉grunt当我们在终端中启动 grunt 时需要执行哪些任务
  grunt.registerTask('dev', ['uglify','watch']);
};
官网:https://
优点:
  • 灵活,只负责执行定义的任务

  • 大量可复用的插件封装好了常见的构建任务

缺点:

  • 集成度不高,要写很多配置后才可以使用,无法开箱即用。与gulp类似


Fis3

Fis3是百度开源的优秀国产构建工具。相对于gulp、Grunt这些只提供基本功能的工具,Fis3集成了web开发中的常用构建能力,如下所述:

  • 读写文件:通过 fis.match 读文件,release 配置文件输出路径。
  • 资源定位:解析文件之间的依赖关系和文件位置。
  • 文件指纹:通过 useHash 配置输出文件时给文件 URL 加上 md5 戳来优化浏览器缓存。
  • 文件编译:通过 parser 配置文件解析器做文件转换,例如把 ES6 编译成 ES5。
  • 压缩资源:通过 optimizer 配置代码压缩方法。
  • 图片合并:通过 spriter 配置合并 CSS 里导入的图片到一个文件来减少 HTTP 请求数。

示例代码:

// 加 md5
fis.match('*.{js,css,png}', {
  useHash: true
});
 
// fis3-parser-typescript 插件把 TypeScript 文件转换成 JavaScript 文件
fis.match('*.ts', {
  parser: fis.plugin('typescript')
});
 
// 对 CSS 进行雪碧图合并
fis.match('*.css', {
  // 给匹配到的文件分配属性 `useSprite`
  useSprite: true
});
 
// 压缩 JavaScript
fis.match('*.js', {
  optimizer: fis.plugin('uglify-js')
});
 
// 压缩 CSS
fis.match('*.css', {
  optimizer: fis.plugin('clean-css')
});
 
// 压缩图片
fis.match('*.png', {
  optimizer: fis.plugin('png-compressor')
});
优点:
  • 集成web开发中常见场景的构建能力,配置简单开箱即用

缺点:

  • 官方不再维护,不支持新版Node.js













应用实践














以webpack4为例介绍在项目中的应用

webpack是一种前端资源构建工具,一个静态模块打包器

在webpack看来,前端的所有资源(js/css/json/img/less...)都会作为模块处理。它根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)

构建流程

webpack会从打包入口开始,找到所有依赖(js/css/json/img/less...),webpack会将这些依赖作为chunk块(代码块),然后将chunk块中的各种文件内容转换为浏览器可以理解的内容:less -> css,es6语法 -> 浏览器可以理解的语法。。。这些转变后的打包产物称为bundle

图片

核心概念

Entry

入口(Entry)指示webpack以哪个文件作为入口起点开始打包,分析构建内部依赖图

Output

输出(Output)指示webpack打包后的资源bundles输出到哪里去,以及如何命名

Loader

加载器(Loader)让webpack能够处理非JavaScript文件(webpack自身只能理解JavaScript)。loader将webpack不识别的资源翻译为webpack识别的资源

Plugins

插件(Plugins)可以用于执行范围更广的任务,包括从打包优化压缩 ,一直到重新定义环境变量

Mode

模式(Mode)指示webpack使用相应模式的配置

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多