前端打包工具介绍和对比

您所在的位置:网站首页 xshell怎么把字体调大 前端打包工具介绍和对比

前端打包工具介绍和对比

2023-04-29 18:40| 来源: 网络整理| 查看: 265

在日常项目开发中构建工具是必不可少的,所以也是我们需要掌握学习的一个重要部分,在技术蓬勃发展的今天,许多优秀的构建工具涌现出来,前端主流打包工具主要有 grunt,gulp,rollup,webpack,vite,parcel等

那么接下来我们就介绍下比较常用的三个打包工具rollup,webpack,vite对比下这几个打包工具的优缺点和适用场景

rollup---适合打包类库

Rollup 是一个 JavaScript 模块打包器,他所负责的工作只是把我们写的代码转化为js

特点:原生支持tree shaking(去除无用代码),支持同时生成umd、commonjs,es的代码

缺点:

模块过于静态化,HMR很难实现 仅面向ES module,无法可靠的处理commonjs以及umd依赖

rollup基本配置

import resolve from 'rollup-plugin-node-resolve';// 提供解析import引入第三方依赖支持(node_modules里的文件) import commonjs from '@rollup/plugin-commonjs';//插件将它们转换为ES6版本 import postcss from 'rollup-plugin-postcss'; import image from '@rollup/plugin-image'; import babel from 'rollup-plugin-babel';//将代码转译为浏览器或者node支持的语法, import json from 'rollup-plugin-json'//引入该插件可以让源码中可以用import引入json文件 import serve from 'rollup-plugin-serve';//本地服务 import livereload from 'rollup-plugin-livereload';//热更新 const input = 'src/index.js' export default { input, // 打包入口//必填 external:[],//指出应该将哪些模块看做外部模块,不和我们的源码包打在一起,该参数接收数组或者参数为模块名称的函数,返回true则将被看做外部引入不打包在一起 output: [{ // 打包出口 file: 'dist/index.js', // 最终打包出来的文件路径和文件名,这里是在package.json的browser: 'dist/index.js'字段中配置的 format: 'umd', // 必填//umd是兼容amd/cjs/iife的通用打包格式,适合浏览器//不设置该选项导出代码无法执行(无法识别export) name:'index',//导出的文件名称//必填 globals:{//设置全局变量? jquery:"$" } }, { file: input.replace('src/', 'dist/').replace('.js', '.cjs'), format: 'cjs' },{ file: input.replace('src/', 'dist/').replace('.js', '.mjs'), format: 'esm' }], plugins: [ // 打包插件 postcss({ extensions: [ '.css' ], }), resolve(), // 查找和打包node_modules中的第三方模块 commonjs(), // 将 CommonJS 转换成 ES2015 模块供 Rollup 处理,用在其他插件转换源码之前,放置其他插件改变破坏CommonJS的检测 babel({ exclude: 'node_modules/**' // 只转译我们的源代码 }), image(), json(),//让源码可以引入json 文件 // 热更新 默认监听根文件夹 livereload({watch:'dist'}), // 本地服务器 serve({ open: true, // 自动打开页面 port: 8000, openPage: '/src/test.html', // 打开的页面 contentBase: '' }) ] }; 复制代码 webpack---适合打包项目

配置项复杂,社区丰富 在webpack项目中需要使用的静态资源,css,以及less等预处理器需要手动引入对应的loader才能使用, 支持代码分割,热更新,丰富的插件系统,通过使用loader可以解析各种类型的资源等

缺点:冷启动,热更新随着项目体量增大而变慢,体量大的项目热更新一次甚至需要几分钟

webpack的底层原理 找到入口->形成文件之间的依赖关系树=>通过loader处理对应资源=>生成打包结果=>启动本地服务进行渲染=>浏览器请求,整个包返回

在整个工作过程的每个环节都有预留钩子,插件可以在不同环节进行一些自定义任务

webpack原理图:

image.png

webpack基本配置

//webpack.base.config.js const path = require('path')// 引入 path 模块 const CopyWebpackPlugin = require('copy-webpack-plugin')// 引入静态资源复制插件 const isProduction = process.env.NODE_ENV === 'production'// 判断当前环境是否是生产环境 const MiniCssExtractPlugin = require('mini-css-extract-plugin')// 样式单独分离到一个文件中 module.exports = { // 打包入口地址 entry: { // 由于可能是多页,所以采用对象的形式 index: ['./src/views/index/index.js'] }, // 模块resolve的规则 resolve: { //自动的扩展后缀,比如一个js文件,则引用时书写可不要写.js extensions: ['.js', '.json', '.css', '.less'], // 路径别名 alias: { '@': path.join(__dirname, '../src') } }, // 构建目标 target: ['web', 'es5'], // context 是 webpack entry 的上下文,是入口文件所处的目录的绝对路径,默认情况下是当前根目录。 // 由于我们 webpack 配置文件放于 build 目录下,所以需要重新设置下 context ,使其指向根目录。 context: path.resolve(__dirname, '../'), plugins: [ // 把public的一些静态文件复制到指定位置,排除 html 文件 new CopyWebpackPlugin({ patterns: [ { from: path.resolve(__dirname, '../public'), globOptions: { dot: true, gitignore: false, ignore: ['**/*.html'] } } ] }) ], module: { // 不同类型模块的处理规则 rules: [// 处理 css、less 文件 { test: /\.(css|less)$/, use: [ isProduction ? MiniCssExtractPlugin.loader : 'style-loader', { loader: 'css-loader', options: { sourceMap: !isProduction, // 是否使用source-map esModule: false// 兼容IE11 } }, { loader: 'postcss-loader', options: { sourceMap: !isProduction // 是否使用source-map } }, 'less-loader' ] }, {// 解析 html 中的 src 路径 test: /\.html$/, use: 'html-loader' }, {// 对图片资源文件进行处理,webpack5已经废弃了url-loader,改为type test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, type: 'asset', exclude: [path.resolve(__dirname, 'src/assets/imgs')], generator: { filename: 'imgs/[name].[contenthash][ext]' } }, {// 对字体资源文件进行处理,webpack5已经废弃了url-loader,改为type test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, type: 'asset', generator: { filename: 'fonts/[name].[contenthash][ext]' } }, {// 对音频资源文件进行处理,webpack5已经废弃了url-loader,改为type test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, type: 'asset', exclude: [path.resolve(__dirname, 'src/assets/medias')], generator: { filename: 'medias/[name].[contenthash][ext]' } }, { test: /\.(m|j)s$/, exclude: /node_modules/, use: [ { loader: 'babel-loader', options: { cacheDirectory: true } } ] } ] } } 复制代码 //webapck.dev.config.js const { merge } = require('webpack-merge')// 引入合并对象插件 const path = require('path')// 引入 path 模块 const HtmlWebpackPlugin = require('html-webpack-plugin')// 引入打包html插件 const baseWebpackConfig = require('./webpack.base.config')// 引入基础配置文件 const devWebpackConfig = merge(baseWebpackConfig, { // 模式,必填项 mode: 'development', // 开启持久化缓存 cache: { type: 'filesystem', buildDependencies: { config: [__filename] } }, output: { // 输出文件目录 path: path.resolve(__dirname, '../dist'), // 输出文件名 filename: 'js/[name].js', }, // 源码映射 devtool: 'eval-cheap-module-source-map', // 开发服务配置 devServer: { // 服务器 host,默认为 localhost host: '0.0.0.0', // 服务器端口号,默认 8080 port: 7001, // 静态资源属性 static: { // 挂载到服务器中间件的可访问虚拟地址 // 例如设置为 /static,在访问服务器静态文件时,就需要使用 /static 前缀 // 相当于[email protected]的 contentBasePublicPath 属性 publicPath: './', // 告诉服务器从哪里提供内容 directory: path.join(__dirname, '../public') }, // 需要监听的文件,由于是多页应用,无法实现热更新,所以都只能刷新页面 watchFiles: ['src/**/*'] }, // 插件 plugins: [ new HtmlWebpackPlugin({ template: './src/views/index/index.html', favicon: path.resolve(__dirname, '../public/favicon.ico') }) ] }) module.exports = devWebpackConfig 复制代码 vite---适合打包项目

开箱即用 对于项目中需要的静态资源,html,less等无需手动引入loader来处理这些资源,直接引入对应的库即可

vite的底层原理 开启web服务器=>浏览器请求对应资源=>本地服务器编译对应文件=>编译结果返回给浏览器渲染;

vite原理图

image.png 启动服务器=> 请求模块时按需动态编译显示;跟webpack相比开发环境的又是在项目大的时候优势就很明显了

开发环境:

基于esbuild进行预构建,不进行打包操作,依托于浏览器本身对es module的解析,热更新时只更新修改部分,从而达到短时间更新的效果

生产环境:

通过rollup进行打包,rollup支持原生的tree shaking所以打出来的包体量小 配置项主要分为以下几大类,

resolve,plugins等共享配置, build,打包配置 build.rollupOptions(rollup底层的配置,将合并vite本身默认的rollup选项), server,本地服务配置 preview,预览配置 optimizeDeps, ssr:服务端渲染配置

vite基本配置

import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import jsx from '@vitejs/plugin-vue-jsx' // 加别名的三种方法 // const path = require("path");//2 import { resolve } from "path" //3 主要用于alias文件路径别名 // // 加别名的函数3 // function pathResolve(dir) { // return resolve(__dirname, ".", dir) // } // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue(),jsx()], resolve:{ alias:[{//1别名配置 find: '@', replacement: '/src', },{ find: '_v', replacement: '/src/views', },{ find: '_c', replacement: '/src/components', }], // alias:{ "/c": path.resolve(__dirname, "./src/components"),},//2需要用绝对路径 // alias:{ "/c": pathResolve("src/components"),},//3文件格式已被处理,根目录前不用加/ extensions:['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json','vue'] }, build: { rollupOptions: { input: { main: resolve(__dirname, 'index.html'), // nested: resolve(__dirname, 'nested/index.html') } } }, server:{ hmr: true, // 开启热更新 proxy:{ // 选项写法 '/api': { target: 'http://jsonplaceholder.typicode.com', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') }, } } }) 复制代码 对比项rollupwebpackvite启动速度/慢:运行机制:会先进行打包操作,完成之后服务再去请求资源,时间自然就长了 ;底层原理:js写的快:运行机制:不进行打包操作就不用分析模块依赖,编译等操作,直接启动开发服务器,然后按需编译(得益于现代浏览器本身支持es-module);底层原理:基于esbuild进行预构建,速度只有webpack的2%-3%;esbuild用go写的,速度比js写的快10-100倍,go(纳秒级)语言本身相对js(毫秒级)来说就有很大的优势,(并行,线程之间共享内存等)blog.csdn.net/weixin_4386…热更新速度/慢:需要重新将这个模块的所有依赖重新编译快:某个模块内容改变,重新请求该模块打包速度打包体积大小借助es6模块的静态分析,只打包用的到代码,比Webpack和Browserify使用的CommonJS模块机制更高效需手动优化,通过插件(uglify)来进行代码压缩 tree shaking有默认配置项,利用rollup进行打包,rollup原生支持tree shaking和esm配置难度小大小,开箱即用,有默认的优化配置兼容性//开发环境因为esm不支持IE,移动端百度,uc不支持生态,社区活跃度活跃度高,社区丰富,老牌打包工具新崛起的工具,社区相比webpack没那么丰富使用上/文件结构不同,可以用require引入资源,通过process.env获取环境变量等项目中不支持reuqire,通过import引入资源,importa.env获取环境变量,变量名必须以VITE_开头 问题集锦 既然esbuild构建速度这么快为什么vite不用esbuild打包呢?

答:目前暂不支持代码分隔和css相关处理,但是生产环境的代码仍需一些分包功能来提升应用性能

vite使用问题集锦(vite2.x+vue2.x)

使用jsx报错,在script里加上lang="jsx" 不支持require改用import下的方法引入资源,官方解释,ssr不支持require 静态资源导入可使用一下两种方法进行导入替代require,或者直接使用路径导入

image.png

image.png



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3