webpack常用loader和plugin

源代码 2024-10-4 11:04:32 54 0 来自 中国
Loader

简介

webpack中提供了一种处置处罚多种文件格式的机制,这便是Loader,我们可以把Loader当成一个转换器,它可以将某种格式的文件转换成Wwebpack支持打包的模块。
在Webpack中,齐备皆模块,我们常见的Javascript、CSS、Less、Typescript、Jsx、图片等文件都是模块,差别模块的加载是通过模块加载器来同一管理的,当我们必要利用差别的 Loader 来剖析差别范例的文件时,我们可以在module.rules字段下设置相干规则。
loader特点


  • loader 本质上是一个函数,output=loader(input) // input可为工程源文件的字符串,也可是上一个loader转化后的效果;
  • 第一个 loader 的传入参数只有一个:资源文件(resource file)的内容;
  • loader支持链式调用,webpack打包时是按照数组从后往前的次序将资源交给loader处置处罚的。
  • 支持同步或异步函数。
代码结构

代码结构通常如下:
// source:资源输入,对于第一个执行的 loader 为资源文件的内容;后续执行的 loader 则为前一个 loader 的执行效果// sourceMap: 可选参数,代码的 sourcemap 结构// data: 可选参数,别的必要在 Loader 链中通报的信息,好比 posthtml/posthtml-loader 就会通过这个参数通报参数的 AST 对象const loaderUtils = require('loader-utils');module.exports = function(source, sourceMap?, data?) {  // 获取到用户给当前 Loader 传入的 options  const options = loaderUtils.getOptions(this);  // TODO: 此处为转换source的逻辑  return source;};常用的Loader

1. babel-loader

babel-loader基于babel,用于剖析JavaScript文件。babel有丰富的预设和插件,babel的设置可以直接写到options里大概单独写道设置文件里。
Babel是一个Javscript编译器,可以将高级语法(紧张是ECMAScript 2015+ )编译成欣赏器支持的低版本语法,它可以资助你用最新版本的Javascript写代码,进步开发服从。
webpack通过babel-loader利用Babel。
****用法****:
# 环境要求:webpack 4.x || 5.x | babel-loader 8.x | babel 7.x # 安装依靠包:npm install -D babel-loader @babel/core @babel/preset-env webpack然后,我们必要创建一个Babel设置文件来指定编译的规则。
Babel设置里的两大核心:插件数组(plugins) 和 预设数组(presets)。
Babel 的预设(preset)可以被看作是一组Babel插件的聚集,由一系列插件构成。
****常用预设:****

  • @babel/preset-env              ES2015+ 语法
  • @babel/preset-typescript    TypeScript
  • @babel/preset-react            React
  • @babel/preset-flow              Flow
****插件和预设的执行次序:****

  • 插件比预设先执行
  • 插件执行次序是插件数组从前向后执行
  • 预设执行次序是预设数组从后向前执行
****webpack设置代码:****
// webpack.config.jsmodule: {  rules: [    {      test: /\.m?js$/,      exclude: /node_modules/,      use: {        loader: 'babel-loader',        options: {          presets: [            ['@babel/preset-env', { targets: "defaults" }]          ],          plugins: ['@babel/plugin-proposal-class-properties'],          // 缓存 loader 的执行效果到指定目次,默以为node_modules/.cache/babel-loader,之后的 webpack 构建,将会实行读取缓存          cacheDirectory: true,        }      }    }  ]}以上options参数也可单独写到设置文件里,许多其他工具都有雷同的设置文件:ESLint (.eslintrc)、Prettier (.prettierrc)。
设置文件我们一样平常只必要设置 presets(预设数组) 和 plugins(插件数组) ,其他一样平常也用不到,代码示比方下:
// babel.config.jsmodule.exports = (api) => {    return {        presets: [            '@babel/preset-react',            [                '@babel/preset-env', {                    useBuiltIns: 'usage',                    corejs: '2',                    targets: {                        chrome: '58',                        ie: '10'                    }                }            ]        ],        plugins: [            '@babel/plugin-transform-react-jsx',            '@babel/plugin-proposal-class-properties'        ]    };};****保举阅读:****

  • babel设置文件相干文档
  • 插件手册
2. ts-loader

为webpack提供的 TypeScript loader,打包编译Typescript
****安装依靠:****
npm install ts-loader --save-devnpm install typescript --dev****webpack设置如下:****
// webpack.config.jsonmodule.exports = {  mode: "development",  devtool: "inline-source-map",  entry: "./app.ts",  output: {    filename: "bundle.js"  },  resolve: {    // Add `.ts` and `.tsx` as a resolvable extension.    extensions: [".ts", ".tsx", ".js"]  },  module: {    rules: [      // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`      { test: /\.tsx?$/, loader: "ts-loader" }    ]  }};还必要typescript编译器的设置文件****tsconfig.json****:
{  "compilerOptions": {    // 目标语言的版本    "target": "esnext",    // 天生代码的模板标准    "module": "esnext",    "moduleResolution": "node",    // 允许编译器编译JS,JSX文件    "allowJS": true,    // 允许在JS文件中报错,通常与allowJS一起利用    "checkJs": true,    "noEmit": true,    // 是否天生source map文件    "sourceMap": true,    // 指定jsx模式    "jsx": "react"  },  // 编译必要编译的文件或目次  "include": [    "src",    "test"  ],  // 编译器必要清除的文件或文件夹  "exclude": [    "node_modules",    "**/*.spec.ts"  ]}更多设置请看 官网
3. markdown-loader

markdown编译器息争析器
****用法:****
只需将 loader 添加到您的设置中,并设置 options。
****js代码里引入markdown文件:****
// file.jsimport md from 'markdown-file.md';console.log(md);****webpack设置:****
// wenpack.config.jsconst marked = require('marked');const renderer = new marked.Renderer();module.exports = {  // ...  module: {    rules: [      {        test: /\.md$/,        use: [            {                loader: 'html-loader'            },            {                loader: 'markdown-loader',                options: {                    pedantic: true,                    renderer                }            }        ]      }    ],  },};4. raw-loader

可将文件作为字符串导入
// app.jsimport txt from './file.txt';// webpack.config.jsmodule.exports = {  module: {    rules: [      {        test: /\.txt$/,        use: 'raw-loader'      }    ]  }}5. file-loader

用于处置处罚文件范例资源,如jpg,png等图片。返回值为publicPath为准
// file.jsimport img from './webpack.png';console.log(img); // 编译后:https://www.tencent.com/webpack_605dc7bf.png// webpack.config.jsmodule.exports = {  module: {    rules: [      {        test: /\.(png|jpe?g|gif)$/i,        loader: 'file-loader',        options: {          name: '[name]_[hash:8].[ext]',          publicPath: "https://www.tencent.com",        },      },    ],  },};css文件里的图片路径酿成如下:
/* index.less */.tag {  background-color: red;  background-image: url(./webpack.png);}/* 编译后:*/background-image: url(https://www.tencent.com/webpack_605dc7bf.png);6. url-loader:

它与file-loader作用相似,也是处置处罚图片的,只不外url-loader可以设置一个根据图片巨细举行差别的操纵,假如该图片巨细大于指定的巨细,则将图片举行打包资源,否则将图片转换为base64字符串归并到js文件里。
module.exports = {  module: {    rules: [      {        test: /\.(png|jpg|jpeg)$/,        use: [          {            loader: 'url-loader',            options: {              name: '[name]_[hash:8].[ext]',              // 这里单元为(b) 10240 => 10kb              // 这里假如小于10kb则转换为base64打包进js文件,假如大于10kb则打包到对应目次              limit: 10240,            }          }        ]      }    ]  }}7. svg-sprite-loader

会把引用的 svg文件 塞到一个个 symbol 中,归并成一个大的SVG sprite,利用时则通过 SVG 的 <use> 传入图标 id 后渲染出图标。末了将这个大的 svg 放入 body 中。symbol的id假如不特别指定,就是你的文件名。
该loader可以搭配****svgo-loader**** 一起利用,svgo-loader是svg的优化器,它可以删除和修改SVG元素,折叠内容,移动属性等,具体不睁开形貌。感爱好的可以移步 [官方介绍]https://github.com/svg/svgo-loader)。
****用途:可以用来开发同一的图标管理库。****
1.png ****示例代码:****
// js文件里用法import webpack from './webpack/webpack.svg';const type = 'webpack';const svg =  `<svg>    <use xlink:href="#${type}"/>  </svg>`;const dom = `<div插件列表 或 搜索目次 找到它们</p>相识更多请移步 链接
11. less-loader

剖析less,转换为css
****代码示例见上文 postcss-loader****
相识更多请移步 链接
Plugin

Plugin简介

Webpack 就像一条生产线,要颠末一系列处置处罚流程后才华将源文件转换成输出效果。 这条生产线上的每个处置处罚流程的职责都是单一的,多个流程之间有存在依靠关系,只有完成当前处置处罚后才华交给下一个流程行止置处罚。 插件就像是一个插入到生产线中的一个功能,在特定的机会对生产线上的资源做处置处罚。
Webpack 通过 Tapable 来构造这条复杂的生产线。 Webpack 在运行过程中会广播事件,插件只必要监听它所关心的事件,就能加入到这条生产线中,去改变生产线的运作。 Webpack 的事件流机制包管了插件的有序性,使得整个体系扩展性很好。
——「深入浅出 Webpack」
常用Plugin

1. copy-webpack-plugin

将已经存在的单个文件或整个目次复制到构建目次。
const CopyPlugin = require("copy-webpack-plugin");module.exports = {  plugins: [    new CopyPlugin({      patterns: [        {           from: './template/page.html',           to: `${__dirname}/output/cp/page.html`         },      ],    }),  ],};2. html-webpack-plugin

基本作用是天生html文件

  • 单页应用可以天生一个html入口,多页应用可以设置多个html-webpack-plugin实例来天生多个页面入口
  • 为html引入外部资源如script、link,将entry设置的相干入口chunk以及mini-css-extract-plugin抽取的css文件插入到基于该插件设置的template文件天生的html文件内里,具体的方式是link插入到head中,script插入到head或body中。
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {  entry: {    news: [path.resolve(__dirname, '../src/news/index.js')],    video: path.resolve(__dirname, '../src/video/index.js'),  },  plugins: [    new HtmlWebpackPlugin({      title: 'news page',      // 天生的文件名称 相对于webpackConfig.output.path路径而言      filename: 'pages/news.html',      // 天生filename的文件模板      template: path.resolve(__dirname, '../template/news/index.html'),      chunks: ['news']    }),    new HtmlWebpackPlugin({      title: 'video page',      // 天生的文件名称      filename: 'pages/video.html',      // 天生filename的文件模板      template: path.resolve(__dirname, '../template/video/index.html'),      chunks: ['video']    }),  ]};3. clean-webpack-plugin

默认环境下,这个插件会删除webpack的output.path中的全部文件,以及每次乐成重新构建后全部未利用的资源。
这个插件在生产环境用的频率非常高,由于生产环境经常会通过 hash 天生许多 bundle 文件,假如不举行整理的话每次都会天生新的,导致文件夹非常巨大。
const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {    plugins: [        new CleanWebpackPlugin(),    ]};4. mini-css-extract-plugin

本插件会将 CSS 提取到单独的文件中,为每个包罗 CSS 的 JS 文件创建一个 CSS 文件。
// 建议 mini-css-extract-plugin 与 css-loader 一起利用// 将 loader 与 plugin 添加到 webpack 设置文件中const MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = {  plugins: [new MiniCssExtractPlugin()],  module: {    rules: [      {        test: /\.css$/i,        use: [MiniCssExtractPlugin.loader, 'css-loader'],      }    ],  },};可以团结上文关于style-loader的介绍一起相识该插件。
5. webpack.HotModuleReplacementPlugin

模块热更换插件,除此之外还被称为 HMR。
该功能会在应用步伐运行过程中,更换、添加或删除 模块,而无需重新加载整个页面。紧张是通过以下几种方式,来明显加速开发速率:

  • 保存在完全重新加载页面期间丢失的应用步伐状态。
  • 只更新变更内容,以节省宝贵的开发时间。
  • 在源代码中 CSS/JS 产生修改时,会立刻在欣赏器中举行更新,这险些相当于在欣赏器 devtools 直接更改样式。
****启动方式有2种:****

  • 引入插件webpack.HotModuleReplacementPlugin 而且设置devServer.hot: true
  • 下令行加 --hot参数
****package.json设置:****
{  "scripts": {    "start": "NODE_ENV=development webpack serve --progress --mode=development --config=scripts/dev.config.js --hot"  }}****webpack的设置如下:****
// scripts/dev.config.js文件const webpack = require('webpack');const path = require('path');const outputPath = path.resolve(__dirname, './output/public');module.exports = {  mode: 'development',  entry: {    preview: [      './node_modules/webpack-dev-server/client/index.js?path=http://localhost:9000',      path.resolve(__dirname, '../src/preview/index.js')    ],  },  output: {    filename: 'static/js/[name]/index.js',    // 动态天生的chunk在输出时的文件名称    chunkFilename: 'static/js/[name]/chunk_[chunkhash].js',    path: outputPath  },  plugins: [    // 大多数环境下不必要任何设置    new webpack.HotModuleReplacementPlugin(),  ],  devServer: {        // 仅在必要提供静态文件时才举行设置        contentBase: outputPath,        // publicPath: '', // 值默以为'/'        compress: true,        port: 9000,        watchContentBase: true,        hot: true,        // 在服务器启动后打开欣赏器        open: true,        // 指定打开欣赏器时要欣赏的页面        openPage: ['pages/preview.html'],        // 将产生的文件写入硬盘。 写入位置为 output.path 设置的目次        writeToDisk: true,    }}****注意:HMR 绝对不能被用在生产环境。****
6. webpack.DefinePlugin

创建一个在编译时可以设置的全局常量。这会对开发模式和生产模式的构建允许差别的活动非常有用。
由于这个插件直接执行文本更换,给定的值必须包罗字符串自己内的实际引号。
通常,有两种方式来到达这个效果,利用'"production"', 大概利用 JSON.stringify('production')
// webpack.config.jsconst isProd = process.env.NODE_ENV === 'production';module.exports = {  plugins: [    new webpack.DefinePlugin({      PAGE_URL: JSON.stringify(isProd        ? 'https://www.tencent.com/page'        : 'http://testsite.tencent.com/page'      )    }),  ]}// 代码内里直接利用console.log(PAGE_URL);7. webpack-bundle-analyzer

可以看到项目各模块的巨细,可以按需优化.一个webpack的bundle文件分析工具,将bundle文件以可交互缩放的treemap的情势展示。
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;module.exports = {  plugins: [    new BundleAnalyzerPlugin()  ]}****启动服务:****

  • 生产环境查察:NODE_ENV=production npm run build
  • 开发环境查察:NODE_ENV=development npm run start
****终极效果:****
相识更多请移步 链接
8. SplitChunksPlugin

代码分割。
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;module.exports = {  optimization: {    splitChunks: {      // 分隔符      // automaticNameDelimiter: '~',      // all, async, and initial      chunks: 'all',      // 它可以继承/覆盖上面 splitChunks 中全部的参数值,除此之外还额外提供了三个设置,分别为:test, priority 和 reuseExistingChunk      cacheGroups: {        vendors: {          // 表现要过滤 modules,默以为全部的 modules,可匹配模块路径或 chunk 名字,当匹配的是 chunk 名字的时间,其内里的全部 modules 都会选中          test: /[\\/]node_modules\/antd\//,          // priority:表现抽取权重,数字越大表现优先级越高。由于一个 module 大概会满意多个 cacheGroups 的条件,那么抽取到哪个就由权重最高的说了算;          // priority: 3,          // reuseExistingChunk:表现是否利用已有的 chunk,假如为 true 则表现假如当前的 chunk 包罗的模块已经被抽取出去了,那么将不会重新天生新的。          reuseExistingChunk: true,          name: 'antd'        }      }    }  },}
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 16:47, Processed in 0.156823 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表