【学习】对工程化、wepack的理解

257 阅读3分钟

【学习】对工程化、wepack的理解

前端的理解

浏览器会识别解析渲染html、css、js等生成页面,而一些比较新的html、css、js的api和vue、less、sass等浏览器是无法识别的,所以就需要用到webpack、gulp、grunt、vite、rollup、rolldown等工具解析转成浏览器能识别的语言渲染成页面。

webpack

webpack解析的几个流程

1.输入 --> 2.生成模块依赖并解析(代码分割、模块合并、TreeShaing、压缩等优化策略) --> 3.输出

输入

1.SPA应用通常只有一个输入文件
2.MPA应用有多个输入文件
 entry: {
      "entry.page1": "./app/pages/page1/entry.page1.js",
      "entry.page2": "./app/pages/page2/entry.page2.js",
    },

生成模块依赖并解析(代码分割、模块合并、TreeShaing、压缩等优化策略)

由于webpack只能识别js,收集模块依赖时,会有多种不同的文件后缀和路径查找,便于开发者开发,可以直接配置自动添加后缀名和配置别名进行依赖收集。

    extensions: [".js", ".vue", ".less", ".css"],
    alias: {
      $pages: path.resolve(process.cwd(), "./app/pages"),
      $common: path.resolve(process.cwd(), "./app/pages/common"),
      $widgets: path.resolve(process.cwd(), "./app/pages/widgets"),
      $store: path.resolve(process.cwd(), "./app/pages/store"),

解析时对于哪些非js的编码webpack无法识别,而webpack loader是可以将编码转成js,我们可以自己编写一个loader将指定文件转成js,也可以使用第三方库。

rules: [
      {
        test: /\.vue$/,
        use: {
          loader: "vue-loader",
        },
      },
      {
        test: /\.js$/,
        // 只对业务代码进行 babel, 加快 webpack 打包速度
        include: [path.resolve(process.cwd(), "./app/pages")],
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.(png | jpe?g| gif)(\?.+)?$/,
        use: {
          loader: "url-loader",
          options: {
            limit: 300,
            esModule: false,
          },
        },
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },
      {
        test: /\.(eot | svg | ttf | woff| woff2)(\?\S*)?$/,
        use: "file-loader",
      },
    ],

webpack plugin可以在解析webpack的某个生命周期中添加一些全局变量或是一些功能。

    // 处理 .vue 文件
    //  它是将你定义过的其他规则复制并应用到.vue 文件里
    // 例如: 如果有一天匹配规则 /\.js$/ 的规则,那么它会应用到 .vue 文件中的 <script>模块中
    new VueLoaderPlugin(),
    // 把第三库暴露到 window context下
    new webpack.ProvidePlugin({
      Vue: "vue",
      axios: "axios",
      _: "lodash",
    }),
    // 定义全局变量
    new webpack.DefinePlugin({
      __VUE_OPTIONS_API__: true, // 支出 vue 解析 optionApi
      __VUE_PROD_DEVTOOLS: false, // 禁用 vue 调试工具
      __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false, // 禁用生产环境显示 "水合" 信息
    }),
    // 构建最终渲染的页面模版
    new HtmlWebpackPlugin({
      //产物(最终模版) 输出路径
      filename: path.resolve(
        process.cwd(),
        "./app/public/dist/",
        "entry.page1.tpl"
      ),
      // 指定要使用模版文件
      template: path.resolve(process.cwd(), "./app/view/entry.tpl"),
      // 要注入的代码块
      chunks: ["entry.page1"],
    }),

打包优化,对于稳定的第三包和业务的公共编码,常规编码,以及webpack运行时注入的编码进行分包,利用浏览器的缓存做优化

/**
     * 把js 文件打包成3种类型
     * 1.vendor:第三方 lib库 ,基本不会变动,除非依赖升级
     * 2.common:业务组件代码的公共部分抽取出来,改动比较少
     * 3.entry.{page}: 不同页面 entry 里的业务组件代码的差异部分,会经常改动
     * 目的:把改动和引用频率不一样的 js 区分出来,以达到更好的浏览器缓存的效果
     */
    splitChunks: {
      chunks: "all", // 对同步和异步模块都进行分割
      maxAsyncRequests: 10, //每次异步加载的最大并行请求数
      maxInitialRequests: 10, //入口点的最大并行请求数
      cacheGroups: {
        // 第三方依赖库
        vendor: {
          test: /[\\/]node_modules[\\/]/, //匹配打包 node_modules 文件
          name: "vendor", //模块名称
          priority: 20, //优先级,数字越大,优先级越高
          enforce: true, // 强制执行
          reuseExistingChunk: true, //复用已有的公共 chunk
        },
        //公共模块
        common: {
          name: "common", //模块名称
          minChunks: 2, // 被两处引用即被视为公共模块
          minSize: 1, //最小分割文件大小 (1byte)
          priority: 10, //优先级
          reuseExistingChunk: true, //复用已有的公共 chunk
        },
      },
    },
    // 将webpack 运行时生成的代码打包到 runtime.js
    runtimeChunk: true,

输出

解析压缩完成生成hash输出到指定的文件目录下

    filename: "js/[name]_[chunkhash:5].bundle.js",
    path: path.join(process.cwd(), "./app/public/dist/prod"),
    publicPath: "/dist/prod",
    crossOriginLoading: "anonymous",

总结

页面需要的html、css、js,使用vue写页面是便于前端模块开发维护,就需要一个工具将vue里的编码转成页面需要的语言。前端工具有很多webpack、gulp、grunt、vite、rollup、rolldown等。

学习前端哲玄