打包工具

所有打包工具是基于 node 运行的

1. Webpack

内置模块

  • path
    • extname: 后缀名
    • basename: 文件名
    • dirname:文件的父级文件夹路径
    • join(x,y): 路径拼接,
    • resolve(): 返回绝对路径

安装

npm webpack webpack-cli -D

webpack-cli: 识别命令行中 webpack 的命令,如果只是在 js 文件中使用 webpack,则不用

webpack 的运行依赖 webpack-cli

基本配置

webpack.config.js固定名字

const path = require('path')
module.exports = {
    mode:'development',   // 默认是生产环境
    context:'',  // 默认值是webpack启动路径,
    entry:'./src/main.js', // 入口 相对于context
    output: {
        filename:'bundle.js'
        path:path.resolve(__dirname,'./build')
    },
    module: {
        rules:[  // 配置loader 解析配置文件
            {
                test:/\.css$/,
                use:[
                   	// 执行顺序是从列表的左边向右解析
             		{loader:'style-loader'}  // 插入到页面中
                    {loader:'css-loader'},  // 只负责解析
            		{
                        loader:'postcss-loader',
                        options:{
                            postcssOptions:{
                                plugins:[
                                	'autoprefixer'
                            	]
                            }
                        }
                    }
                ]
            }
        ]
    }

}

指定配置文件:package.json 中可以通过 stripts:

loader

webpack 对除了 js 文件以外的文件,不支持处理

loader: 处理模块,对源码进行转换

常用 loader:

  • css-loader: 只负责 css 解析

  • style-loader: 将 css 插入页面中

  • less-loader: 解析 less 文件成 css

  • postcss-loader:通过 js 进行转换样式的工具,如浏览器前缀,css 样式的重置

    • autoprefixer: 浏览器前缀插件

      可以通过 postcss.config.js 进行配置,

      module.exports = {
        plugins: [
          // 'autoprefixer'
          "postcss-preset-env",
        ],
      };
      
    • postcss-preset-env: 将很多插件预设好了

  • babel-loader: 将 ES6 转为 ES5

    • @babel/preset-env

      // babel.config.js
      module.exports = {
          //plugins:[
          //    @babel/plugin-xxxxxxxx
          //]
          presets:[
              @babel/preset-env
          ]
      }
      

资源模块

webpack5 之前在处理资源的时候,需要使用各种 loader: raw-loader,url-loader,file-loader,

webpack5 之后,可以直接使用资源模块类型 asset module type

资源模块类型

  1. asset/resource: 发送一个单独的文件并导出 URL , 与 file-loader 对应
  2. asset/inline:导出一个资源的 data URL ,与 url-loader 对应
  3. asset/source:导出资源的源码,与 raw-loader 对应
  4. asset:在导入一个 data URL 和发送一个单独的文件之间自动选择,url-loader 配置资源体积限制实现
// webpack.config.js

...

rules:[
    ...
    {
        test:/\.(png|jpe?g|gif|svg)$/ig,
        type:'asset',
        generator:{
            // 占位符
            // name 文件名
            // ext 扩展名
            // hash hash:2 前两位
            filename:'img/[name].[hash:6][ext]'
        },
        parser:{
            dataUrlCondition:{
                maxSize: 60*1024
            }
        }
    }
]

extensions 和 alias 配置

extensions: 文件扩展名配置

​ 如果是文件,当不写扩展名时,尝试去 extensions 中查找

​ 如果是文件夹,去当前文件夹下查找 index.js

alias: 配置别名

module.exports = {
  //...
  resolve: {
    extensions: [".js", ".json", ".wasm", "vue", "ts"],
  },
  alias: {
    utils: path.resolve(__dirname, "./utils"),
  },
};

插件 Plugin

loader 用来转换特定类型的模块,plugin 可以用于执行更加广泛的任务,如打包优化,资源管理,环境变量注入等

  • clean-webpack-plugin: 清除打包文件

  • html-webpack-plugin:

  • DefinePlugin: 内置的

const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {DefinePlugin} =  require('webpack')
module.exports = {
  //...

  plugins:[
      new CleanWebpackPlugin(),
      new HtmlWebpackPlugin({
          title:'自定义模板',
          template:'./index.html'
      })
      new DefinePlugin({
      	"BASE_URL":'"./"'
      })
  ]
};
// index.html

source-map

将已经转换的代码,映射到原始的源文件,使浏览器可以重构原始源,并且在调试器中显示重建的原始源

使用 source-map

// webpack.config.js
module.exports = {
  ...
  devtool: "source-map", // 26个值可以设置 不同的值会明显影响到构建(build)和重新构建(rebuild)的速度。
  ...
};

浏览器会将转换后的代码中的注释 //# sourceMappingURL=bundle.js.map 加载对应的 sourcemap 文件,并根据 source-map 文件还原我们的代码

devtool 值:

  • none: 默认,production 环境下,不生成 source-map

  • false: 不生成 source-map

  • eval: development 模式下,也不会生成 source-map, 会使用 eval 函数,还原源文件,但是位置信息不准确

  • source-map: production 环境下,生成完整的 source-map 文件

  • eval-source-map: 生成 source-map,会以 DataUrl 添加到 eval 函数的后面

  • inline-source-map: 生成 source-map,会以 DataUrl 添加到文件的后面

  • cheap-source-map: development 模式下,高效一些,不会生成列位置映射,

  • cheap-module-source-map: 对 loader 处理的代码,生成的 source-map 处理的更好

  • hidden-source-map: production 环境下, 生成 source-map 但是不会对文件进行引用,需要手动引用//# sourceMappingURL=bundle.js.map

  • nosource-source-map: 生成的 sourcemap 只有错误信息的提示,不会生成源代码文件

    推荐使用:

    • 开发阶段:source-map 或者 cheap-module-source-map
    • 测试阶段:source-map 或者 cheap-module-source-map
    • 发布阶段:false,缺省值(不写)

分析 source-map

{
  "version": 3, // 版本号 第三版文件大小约是源文件的2.5倍大小
  "file": "bundle.js", // 打包之后的文件
  "mappings": "AACAA,QAAQC,IADQ,eAIdD,QAAQC,IAAI", // 编码,与源文件进行映射,记录位置信息的字符串
  "sources": [
    // 源文件列表
    "webpack://source-map/./src/main.js"
  ],
  "sourcesContent": [
    // 转换前文件的原始内容。
    "const message = \"hello world\";\r\nconsole.log(message);\r\n\r\nconst foo = () => {\r\n  console.log(\"foo function exec~\");\r\n};\r\nfoo();\r\n"
  ],
  "names": [
    // 转换前的所有变量名和属性名。
    "console",
    "log"
  ],
  "sourceRoot": "" // 转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。
}
  • mappings

    • 第一层是行对应,以分号(; )表示,每个分号对应转换后源码的一行。所以,第一个分号前的内容,就对应源码的第一行,以此类推。

    • 第二层是位置对应,以逗号(, )表示,每个逗号对应转换后源码的一个位置。所以,第一个逗号前的内容,就对应该行源码的第一个位置,以此类推。

    • 第三层是位置转换,以VLQ 编码表示,代表该位置对应的转换前的源码位置。

      // 源码转换前
      const message = "hello world";
      console.log(message);
      
      const foo = () => {
        console.log("foo function exec~");
      };
      foo();
      

      源码转换后:

      console.log("hello world"), console.log("foo function exec~");
      

      "mappings": "AACAA,QAAQC,IADQ,eAIdD,QAAQC,IAAI",

      正常来说,每个位置最多由 5 个字母组成,5 个字母的含义分别是:

      • 第一位,表示这个位置在(转换后的代码的)的第几列。
      • 第二位,表示这个位置属于 sources 属性中的哪一个文件。
      • 第三位,表示这个位置属于转换前代码的第几行。
      • 第四位,表示这个位置属于转换前代码的第几列。
      • 第五位,表示这个位置属于 names 属性中的哪一个变量。

      每一个位置都可以用VLQ 编码转换,形成一种映射关系。可以在这个网站自己转换测试,将 AACAA,QAAQC,IADQ,eAIdD,QAAQC,IAAI 转换后的结果:[0,0,1,0,0], [8,0,0,8,1], [4,0,-1,8], [15,0,4,-14,-1], [8,0,0,8,1], [4,0,0,4],

      AACAA [0,0,1,0,0] 表示:

      • 压缩代码的第一列。
      • 第一个源代码文件,main.js
      • 源代码的第二行。
      • 源代码第一列
      • names 中第一个变量

Mode 配置

  • production: 默认
  • none:不使用任何默认优化选项
  • development:开发环境

development

devtool:'eval'  # 设置source-map

production


开启本地服务器

想要自动完成编译和展示

  • webpack watch mode

  • webpack-dev-server

    {
        ...
        scripts:{
            'serve':'webpack serve --config webpack.config.js'
        }
    }
    
    // npm run serve
    
  • webpack-dev-middle

模块热更新(HMR)

应用程序运行过程中,添加、替换、删除模块,无需重新刷新整个页面

{
    ...
    devServer:{
        hot: true  // 默认是true

    }
}

// 指定哪个模块需要HMR

if (module.hot){
    module.hot.accept('./utils.js')
}

devServer 配置

{
    devServer:{
      	port:8888, // 端口号
        host:'0.0.0.0', // 其他都可访问
        open:true, // 是否要自动打开浏览器
        compress:true// 是否对文件进行压缩
    }
}

环境配置

Vue 脚手架早期:

​ webpack.dev.config.js:开发环境

​ webpack.pro.config.js:生产环境

​ webpack.comm.config.js: 公共部分,

​ 使用webpack-merge 将公共部分和私有部分合并, merge(coom,{自定义})

分包

vue3 中使用 import 函数导入模块自动分包

const Home = () => import(/*webpackChunkName: 'home'*/, './views/Home.vue')

2. gulp

3. rollup

4. Vite

posted @ 2023-03-25 23:47  转角90  阅读(55)  评论(0编辑  收藏  举报