• webpack(10) webpack扩展(插件. loader)


    webpack做的事情, 仅仅是分析各个模块间的依赖关系, 将chunk里的资源合并成资源列表, 然后输出打包文件;

    更多的事情, 需要loader和plugin来完成;

    plugin的用法, 通过npm来找用法

    1. clean-webpack-plugin:

           每次打包前清除配置文件中的输出包.

           原理: 注册compiler.hooks的emit事件, 用fs模块删除配置文件的目录;

     注意: 经过我测试, 和多文件应用时候, 必须配置filename属性, 否则clean-webpack-plugin会因为文件名相同而不起作用

    2. HTML Webpack Plugin

         将打包生成的js文件放到html文件中, 然后输出;可以只生成一个html文件, 也可以指定固定的/ 多个模板html

          多页面设置: 使用多次  new HtmlWebpackPlugin({chunks:[]})

     1 module.exports = (env)=>{
     2   return {
     3     mode: env.prod ? "production" : "development",
     4     devtool:  env.prod ? "eval" : "source-map",
     5     plugins:[
     6       new HtmlWebpackPlugin({
     7         title: "My App",
     8         filename:"index.html",
     9         template:"./src/assets/index.html", //指定生成模板
    10         chunks: ['index'] //根据入口中定义的chunks的值生成不同的script标签, 默认是all;
    11       }),
    12       new HtmlWebpackPlugin({
    13         title: "abc",
    14         filename:"abc.html",//这个必须有
    15         template:"./src/assets/abc.html",
    16         chunks: ['abc']
    17       }),
    18       new CleanWebpackPlugin(),
    19     ],
    20     
    21     entry:{
    22       index:"./src/index.js",
    23       abc:"./src/abc.js"
    24     },

    原理:  检查有没有template属性, 有就读取文件, 抽象语法树分析文件,没有就生成一个空的html文件.

              检查是否有chunks的属性, 有就将第一步的文件以script标签的形式输出chunkfs选项的代码 ,生成页面文件输出

    3. copy-webpack-plugin

        作用: 将已存在的静态文件, 单独的,或者全部目录, copy到输出目录中. 即在用到html-webpack-plugin时, 如果html模板文件中有静态文件引入标签, 比如<img src="./img/a.jpg">,则会导致输出的文件中, 找不到img的src,必须将html对应的静态文件打包输出, 这也就是为什么html-webpack-plugin和copy-webpack-plugin一般都同时用的原因.

    new CopyPlugin({
          patterns: [
            { from: "source", to: "dest" },
            { from: "other", to: "public" },
          ],
        }),

      原理, 会根据配置读取copy的目录或文件, 然后打包后输出

    4. dev-server 开发时用的服务器; 

           注意, 该命令是webpack官方出的(文档不在npm上, 在webpack上).能够自动生成一个临时服务器,解决了

    •       频繁npx webpack命令的问题,
    •       开发过程中生成的页面在服务器上模拟真实的环境. 
     用法: 按装: npm install webpack-dev-server --save-dev
          启动命令: npx webpack serve

           webpack server做的操作:

    1. 传递命令行参数,
    2. 开启watch监听,
    3. 注册钩子函数, 保存资源列表, 禁止webpack输出文件,
    4. 开启express服务器, 监听端口, 根据浏览器的请求,返回资源.   

    webpack-dev-server最常用的配置就是代理服务器, 来解决跨域问题:

          情景: 1. 开发时候, 用的localhost:8080端口的服务器环境,因为需要用--watch功能和在服务器上的功能, 比如, 发送ajax请求, 单纯的浏览器上时无法办到的,

                  2 但请求的服务器是后端的, 或者localhost:9000端口, 不管域名还是端口不一致, 就造成了跨域问题, 

                  3. proxy正是解决这个问题的:https://webpack.docschina.org/configuration/dev-server/#devserverport

    module.exports = (env) => {
      return {
        mode: env.prod ? "production" : "development",
        devtool: env.prod ? "eval" : "source-map",
        ...
        devServer: {
          open: true,
          port: 8080,
          proxy: {
            //含义是: 属性名是正则表达式//api/, 如果能匹配, 则将本次请求的协议域名端口换成属性值; 
            //即原本的http://127.0.0.1:8080/api/abc被换成了http://127.0.0.1:3000/api/abc
            "/api": "http://127.0.0.1:3000",
    "changeOrigin": true //是否转换请求头信息, 针对 有些服务器会对非本服务器的请求作出限制 的请求;
    }, }, }

    proxy的配置需要注意的几点: 

    1.如果不希望传递/api,则需要重写路径:

     1 webpack.config.js
     2 
     3 module.exports = {
     4   //...
     5   devServer: {
     6     proxy: {
     7       '/api': {
     8         target: 'http://localhost:3000',
     9         pathRewrite: { '^/api': '' }, //把匹配到的这个内容, 替换成空串
    10       },
    11     },
    12   },
    13 };
        以上配置:fetch('/api/abc') 转换成请求"http://localhost:3000/abc"

    2,代理时会保留主机头的来源,可以将 changeOrigin 设置为 true 以覆盖此行为

    6. file-loader和url-loader的配合使用

        6.1 file-loader

            情景: 当用require方式引入静态文件, 会导致抽象语法树无法解析图片的数据, 

    原因就是在引入.jpg文件后, 抽象语法树不能解析这种二进制数据, 需要loader来帮着转换. 

     

     

     作用: (1)将require("文件路径")这种导入的文件, 作为src地址导出, 

              (2) 将导入的文件导出到输出目录

     原理: function file-loader(source){ //source是文件内容(图片内容的buffer)

              // 1.生成具有相同内容的文件到输出目录

               // 2. 返回一段代码 export default "文件名"

             }

           

    //index.js
    import imgSrc from './assets/img/1.png';// 说明file-loader内部是export default "文件路径"

           注意点:

    1.  这个file-loader是在打包过程中用的, 而不是打包后用到的, 所以应该用npm i -D安装;
    2.  loader和plugin是不一样的, loader是不需要引入的, 可以直接使用; 这是因为loader的配置规则写法和plugin是不一样的, 

                plugins的配置是一个数组, 直接new xxplugin, 所以得提前引入, 而loader用modlue:...user: [xxloader]这种写法, 相当于 用了require了,会找node_module目录下寻找xxloader,然后导入

                    

    module.exports = (env) => {
      return {
        mode: env.prod ? "production" : "development",
        devtool: env.prod ? "eval" : "source-map",
        module: {
          noParse: /jquery|lodash/,
    
          rules: [
            {
              test: /.(png|jpe?g|gif)$/i,
              loader: 'file-loader',//只用一个loader可以直接写,而不需要写use
              options: {
                outputPath: 'images',//也可以写"/images"
                name: '[name]_[hash:5].[ext]'//hash是fileloader生成的.
              },
            },
          ],
        },

    6.2 url-loader 

        url-loader works like file-loader, but can return a DataURL if the file is smaller than a byte limit.
                file-load是生成一个文件到输出目录, 并将模块文件设置成导出路径;

                url-loader是将依赖文件转换成为:导出base64格式的字符串;

               url-loader原理:

           function url-loader(source){ //source是文件内容(图片内容的buffer)

              // 1.将buffer生成一个base64编码

               // 2. 返回一段代码  export default "base64编码"

             }

           url-loader配置注意: urlloader配置完后, 不能单独再配置一个file-loader, 就可以使用

                 A Number or String specifying the maximum size of a file in bytes. If the file size is equal or greater than the limit file-loader will be used (by default) and all query parameters are passed to it.

    module.exports = (env) => {
      return {
        mode: env.prod ? "production" : "development",
        devtool: env.prod ? "eval" : "source-map",
        module: {
          noParse: /jquery|lodash/,
    
          rules: [
            {
              test: /.(png|jpe?g|gif)$/i,
              use: [
                {
                  loader: 'url-loader',
                  options: {
                    limit: 100 * 1024,//只要文件不超过100kb,则使用base64,否则用file-loader
                    //注意, 配置了url-loader后就不能再去单独配置file-loader了,否则会全部使用file-loader
                    //下面的配置会自动传递给file-loader
                    outputPath: 'images',
                    name: '[name]_[hash:5].[ext]'
                  },
                },

    url-loader的作用是: 当文件很小,且数量比较大时候, 如果都用file-loader, 会增加网络请求数量, 这是以文件的体积换取网络请求的数量的

     

    7. output.publicpath对webpack生成的文件的路径影响;

         1. 将webpack.config.js中的output.publicPath设置为一个字符串;

        

     2. 从webpack生成的index.js的源码中可以看出

            2.1 源码中定义了一个公共路径

     

     2.2 在导出图片时候, 导出的内容是output.publicPath + require的参数,

     2.3这样打包形成的所有文件, 都会加上publicPath, 比如经过插件HtmlWebpackPlugin形成的html文件, 它的形成的标签都是加入output.publicPath的;

    这样形成的文件, 打包出来会对路径造成严重影响, 

           

     

     所以, 我们一般配置为打包的网站内容:"/",原因是:

      "/xx"是绝对路径, 会自动请求网站下的路径资源(省略了协议域名端口),如网站是http:www.abc.com; 这样就会自动请求http:www.abc.com/xx

     所有成熟的loader和插件对导出路径都会受到output.publicpath的影响.

     8 .webpack内部插件

    用法: 在配置文件中, 

    //webpack.config.js
    
    const webpack = require('webpack');
    module.exports = {
        plugins:[
             new webpack.BannerPlugin({
                banner: 'hello world',
            }),
    new
    webpack.ProvidePlugin({ //引入常用的库
                  $: 'jquery',
                  jQuery: 'jquery',
               }),
    
            ...
        ]
    }

    1.BannerPlugin : 为每个chunk添加头信息 Add a banner to the top of each generated chunk

    2. ProvidePlugin: 在全局定义常用库

  • 相关阅读:
    Collections集合工具类排序
    集合的学习
    gitee使用方法
    vue 首屏优化
    vue 配置多个路由别名
    vue中的状态管理Vuex
    【Python】Pandas合并表格之(append, join , concat方法)
    elementui中提交表单自动刷新页面的问题
    滴滴实习面试题
    CSS 日常积累
  • 原文地址:https://www.cnblogs.com/dangdanghepingping/p/14529110.html
Copyright © 2020-2023  润新知