前端构建工具生态

介绍

构建工具的主要功能就是实现自动化处理,例如对代码进行检查、预编译、合并、压缩;生成雪碧图、sourceMap、版本管理;运行单元测试、监控等,当然有的工具还提供模块化、组件化的开发流程功能。

  • 基于任务运行的工具:
    Grunt、Gulp
    它们会自动执行指定的任务,就像流水线,把资源放上去然后通过不同插件进行加工,它们包含活跃的社区,丰富的插件,能方便的打造各种工作流。

  • 基于模块化打包的工具:
    Browserify、Webpack、rollup.js、vite
    有过 Node.js 开发经历的应该对模块很熟悉,需要引用组件直接一个 require 就 OK,这类工具就是这个模式,还可以实现按需加载、异步加载模块。

  • 整合型工具:
    Yeoman、FIS、jdf、Athena、cooking、weflow
    使用了多种技术栈实现的脚手架工具,好处是即开即用,缺点就是它们约束了技术选型,并且学习成本相对较高。

webpack

用法

webpack.config.js

module.exports = {
    //插件项
    plugins: [commonsPlugin],
    //页面入口文件配置
    entry: {
        index : './src/js/page/index.js'
    },
    //入口文件输出配置
    output: {
        path: 'dist/js/page',
        filename: '[name].js'
    },
    module: {
        //加载器配置
        loaders: [
            { test: /\.css$/, loader: 'style-loader!css-loader' },
            { test: /\.js$/, loader: 'jsx-loader?harmony' },
            { test: /\.scss$/, loader: 'style!css!sass?sourceMap'},
            { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
        ]
    },
    //其它解决方案配置
    resolve: {
        root: '/Users/Bell/github/flux-example/src', //绝对路径
        extensions: ['', '.js', '.json', '.scss'],
        alias: {
            AppStore : 'js/stores/AppStores.js',
            ActionType : 'js/actions/ActionType.js',
            AppAction : 'js/actions/AppAction.js'
        }
    }
};
  • 把一切都视为模块:不管是 CSS、JS、Image 还是 HTML 都可以互相引用,通过定义 entry.js,对所有依赖的文件进行跟踪,将各个模块通过 loader 和 plugins 处理,然后打包在一起。
  • 按需加载:打包过程中 Webpack 通过 Code Splitting 功能将文件分为多个 chunks,还可以将重复的部分单独提取出来作为 commonChunk,从而实现按需加载。

推荐

rollup

用法

rollup.config.js

import vue from 'rollup-plugin-vue'
import { terser } from 'rollup-plugin-terser'


import { terser } from 'rollup-plugin-terser'
import vue from 'rollup-plugin-vue'

module.exports = [
  {
    input: 'index.js',
    output: [
      {
        file: 'dist/index.js',
        format: 'es'
      }
    ],
    plugins: [
      vue({
        // Dynamically inject css as a <style> tag
        css: true, 
        // Explicitly convert template to render function
        compileTemplate: true
      }),
      terser()
    ]
  }
]
  • Rollup 是一款 ES Modules 打包器,从作用上来看,Rollup 与 Webpack 非常类似。不过相比于 Webpack,Rollup要小巧的多,打包生成的文件更小。(识别commonJs需要插件)
  • 热更新:Rollup不支持HMR,在对js以外的模块的支持上不如webpack,但是如果是打包纯js库例如react,前期的vue的话,使用rollup是很合适的,打包的产物比较干净,没有webpack那么多工具函数
  • Rollup 的插件机制设计得相对更干净简洁,单个模块的 resolve / load / transform 跟打包环节完全解耦,所以 Vite 才能在开发时模拟 Rollup 的插件机制,并且兼容大部分 Rollup 插件
  • rollup原生支持tree-shaking,不管你引用了什么模块,取决于你调用了什么模块,由你调用的模块构建作用域
  • magic-stringRollup 作者写的一个关于字符串操作的库

推荐

vite

用法

vite.config.js

import { defineConfig } from 'vite' // 帮手函数,这样不用 jsdoc 注解也可以获取类型提示
import vue from '@vitejs/plugin-vue'
const { resolve } = require('path')
import { viteMockServe } from "vite-plugin-mock"

const localEnabled = process.env.USE_MOCK || false;
const prodEnabled = process.env.USE_CHUNK_MOCK || false;

// https://vitejs.dev/config/
export default () => defineConfig({
 plugins: [ //配置需要使用的插件列表
    vue(),
    viteMockServe({
        mockPath: "./src/server/mock",
        localEnabled: localEnabled, // 开发打包开关 true时打开mock  false关闭mock
        prodEnabled: prodEnabled,//prodEnabled, // 生产打包开关
        // 这样可以控制关闭mock的时候不让mock打包到最终代码内
        injectCode: `
        import { setupProdMockServer } from './mockProdServer';
        setupProdMockServer();
        `,
        logger: false, //是否在控制台显示请求日志
        supportTs:false //打开后,可以读取 ts 文件模块 打开后将无法监视 .js 文件
    })
 ],
 // 强制预构建插件包
 optimizeDeps: {
    //检测需要预构建的依赖项
    entries: [],
    //默认情况下,不在 node_modules 中的,链接的包不会预构建
    include: ['axios'],
    exclude:['your-package-name'] //排除在优化之外
 },
 //静态资源服务的文件夹
 publicDir: "public",
 base: './',
 //静态资源处理
 assetsInclude: "",
 //控制台输出的级别 info 、warn、error、silent
 logLevel: "info",
 // 设为false 可以避免 vite 清屏而错过在终端中打印某些关键信息
 clearScreen:true,
 resolve: {
    alias: [//配置别名
        { find: '@', replacement: resolve(__dirname, 'src') }
    ],
    // 情景导出 package.json 配置中的exports字段
    conditions: [],
    // 导入时想要省略的扩展名列表
    // 不建议使用 .vue 影响IDE和类型支持
    extensions:['.mjs','.js','.ts','.jsx','.tsx','.json']  
 },
 // css
 css: {
    // 配置 css modules 的行为
    modules: {  },
    // postCss 配置
    postcss: {
    },
    //指定传递给 css 预处理器的选项
    preprocessorOptions:{
        scss: {
            additionalData:`$injectedColor:orange;`
        }
    }
 },
 json: {
    //是否支持从 .json 文件中进行按名导入
    namedExports: true,
    //若设置为 true 导入的json会被转为 export default JSON.parse("..") 会比转译成对象字面量性能更好
    stringify:false
 },
 //继承自 esbuild 转换选项,最常见的用例是自定义 JSX
 esbuild: {
    jsxFactory: "h",
    jsxFragment: "Fragment",
    jsxInject:`import Vue from 'vue'`
 },
 //本地运行配置,以及反向代理配置
 server: {
    host: "localhost",
    https: false,//是否启用 http 2
    cors: true,//为开发服务器配置 CORS , 默认启用并允许任何源
    open: true,//服务启动时自动在浏览器中打开应用
    port: "9000",
    strictPort: false, //设为true时端口被占用则直接退出,不会尝试下一个可用端口
    force: true,//是否强制依赖预构建
    hmr: false,//禁用或配置 HMR 连接
    // 传递给 chockidar 的文件系统监视器选项
    watch: {
        ignored:["!**/node_modules/your-package-name/**"]
    },
    // 反向代理配置
    proxy: { 
        '/api': {
            target: "https://xxxx.com/",
            changeOrigin: true,
            rewrite: (path) => path.replace(/^/api/, '')
        }
    }
 },
 //打包配置
 build: {
    //浏览器兼容性  "esnext"|"modules"
    target: "modules",
    //指定输出路径
    outDir: "dist",
    //生成静态资源的存放路径
    assetsDir: "assets",
    //小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求。设置为 0 可以完全禁用此项
    assetsInlineLimit: 4096,
    //启用/禁用 CSS 代码拆分
    cssCodeSplit: true,
    //构建后是否生成 source map 文件
    sourcemap: false,
    //自定义底层的 Rollup 打包配置
    rollupOptions: {},
    //@rollup/plugin-commonjs 插件的选项
    commonjsOptions: {},
    //构建的库
    lib: {},
    //当设置为 true,构建后将会生成 manifest.json 文件
    manifest: false,
    // 设置为 false 可以禁用最小化混淆,
    // 或是用来指定使用哪种混淆器
    // boolean | 'terser' | 'esbuild'
    minify: "terser", //terser 构建后文件体积更小
    //传递给 Terser 的更多 minify 选项。
    terserOptions: {},
    //设置为 false 来禁用将构建后的文件写入磁盘
    write: true,
    //默认情况下,若 outDir 在 root 目录下,则 Vite 会在构建时清空该目录。
    emptyOutDir: true,
    //启用/禁用 brotli 压缩大小报告
    brotliSize: true,
    //chunk 大小警告的限制
    chunkSizeWarningLimit: 500
 },
 ssr: {
    // 列出的是要为 SSR 强制外部化的依赖
    external: [],
    //列出的是防止被 SSR 外部化依赖项
    noExternal: []
 }
})
  • Vite其核心原理是利用浏览器现在已经支持ES6import,碰见import就会发送一个HTTP请求去加载文件,Vite启动一个 koa 服务器拦截这些请求,并在后端进行相应的处理将项目中使用的文件通过简单的分解与整合,然后再以ESM格式返回返回给浏览器。
  • 快速的冷启动:vite会直接启动开发服务器,不需要进行打包操作,所以不需要分析模块的依赖、不需要编译,因此启动速度非常快
  • 即时的模块热更新
  • 真正的按需编译:利用现代浏览器支持ES Module的特性,当浏览器请求某个模块的时候,再根据需要对模块的内容进行编译,这种方式大大缩短了编译时间

推荐

gulp

用法

Gulpfile.js

var gulp = require('gulp');
var pug = require('gulp-pug');
var less = require('gulp-less');
var minifyCSS = require('gulp-csso');

gulp.task('html', function(){
  return gulp.src('client/templates/*.pug')
    .pipe(pug())
    .pipe(gulp.dest('build/html'))
});

gulp.task('css', function(){
  return gulp.src('client/templates/*.less')
    .pipe(less())
    .pipe(minifyCSS())
    .pipe(gulp.dest('build/css'))
});

gulp.task('default', [ 'html', 'css' ]);
  • Vinyl 是 Gulp 自创的一种用来描述一个虚拟文件的类;Orchestartor,为 gulp.task 提供了全部实现
  • 主要是通过各种 Transform Stream 来实现文件的处理,然后再进行输出
  • gulp是与grunt功能类似的前端项目构建工具, 也是基于Nodejs的自动任务运行器
  • 能自动化地完成 javascript/coffee/sass/less/html/image/css 等文件的 合并、压缩、检查、监听文件变化、浏览器自动刷新、测试等任务
  • gulp更高效(异步多任务), 更易于使用, 插件高质量

推荐

欢迎关注我的前端自检清单,我和你一起成长

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容