zoukankan      html  css  js  c++  java
  • webpack学习记录-认识loader(二)

    Loader 就像是一个翻译员,能把源文件经过转化后输出新的结果,并且一个文件还可以链式的经过多个翻译员翻译。

    loader参考文章:https://webpack.docschina.org/loaders/

    以处理 SCSS 文件为例:

    1. SCSS 源代码会先交给 sass-loader 把 SCSS 转换成 CSS;
    2. 把 sass-loader 输出的 CSS 交给 css-loader 处理,找出 CSS 中依赖的资源、压缩 CSS 等;
    3. 把 css-loader 输出的 CSS 交给 style-loader 处理,转换成通过脚本加载的 JavaScript 代码;

    可以看出以上的处理过程需要有顺序的链式执行,先 sass-loader 再 css-loader 再 style-loader。

    Loader 的职责

    一个 Loader 的职责是单一的,只需要完成一种转换。
    如果一个源文件需要经历多步转换才能正常使用,就通过多个 Loader 去转换。
    在调用多个 Loader 去转换一个文件时,每个 Loader 会链式的顺序执行,
    第一个 Loader 将会拿到需处理的原内容,上一个 Loader 处理后的结果会传给下一个接着处理,最后的 Loader 将处理后的最终结果返回给 Webpack。

    所以,在开发一个 Loader 时,需要保持其职责的单一性,我们只需关心输入和输出。

    了解一些loader

    Babel

    babel 可以让我们使用 ES2015/16/17 写代码而不用顾忌浏览器的问题,Babel 可以帮我们转换代码。首先安装必要的几个 Babel 库

    npm i --save-dev babel-loader babel-core babel-preset-env

    先介绍下我们安装的三个库

    • babel-loader 用于让 webpack 知道如何运行 babel
    • babel-core 可以看做编译器,这个库知道如何解析代码
    • babel-preset-env 这个库可以根据环境的不同转换代码

    安装完后需要更改 webpack-config.js 中的代码

    module.exports = {
    // ......
        module: {
            rules: [
                {
                // js 文件才使用 babel
                    test: /.js$/,
                 // 使用哪个 loader
                    use: 'babel-loader',
                // 不希望babel处理的文件所在的路径
                    exclude: /node_modules/
                }
            ]
        }
    }

    配置 Babel 有很多方式,这里推荐使用 .babelrc 文件管理(如果此文件没有,则新建一个)。

    // ..babelrc
    {
        "presets": ["babel-preset-env"]
    }

     babel-polifill插件

    在上面的babel配置中,babel只是将一些es6,es7-8的语法转换成符合目标的js代码,但是如果我们使用一些特性或方法,比如Generator, Set, 或者一些方法。babel并不能转换为低版本浏览器识别的代码。这时就需要babel-polifill。

    简单的说,polifill就是一个垫片,提供了一些低版本es标准对高级特性的实现。使用polifill的方法如下:

    npm install --save babel-polifill

    然后在应用入口引入polifill,要确保它在任何其他代码/依赖声明前被调用。

    //CommonJS module
    require('babel-polyfill');
    
    //es module
    import 'babel-polifill';

    在webpack.config.js中,将babel-polifill加入entry数组中:

    entry: ["babel-polifill", "./app.js"]

    相比于runtime-transform,polifill用于应用开发中。会添加相应变量到全局,所以会污染全局变量。

    更多细节参考babel-polifill

    runtime-transform插件

    runtime transform也是一个插件,它与polifill有些类似,但它不污染全局变量,所以经常用于框架开发。

    npm install --save-dev bable-plugin-transform-runtime
    
    npm install --save bable-runtime

    用法:将下面内容添加到.bablerc文件中

    {
        "plugins": ["transform-runtime"]
    }

    更多细节参考bable-runtime-transform插件

    处理图片

    使用 url-loader 和 file-loader,这两个库不仅可以处理图片,还有其他的功能

    npm i --save-dev url-loader file-loader

    创建一个 images 文件夹,放入两张不同大小的图片,并且在 app 文件夹下创建一个 js 文件处理图片 ,目前的文件夹结构如图 

    // addImage.js
    let smallImg = document.createElement('img')
    // 必须 require 进来
    smallImg.src = require('../images/small.jpeg')
    document.body.appendChild(smallImg)
    
    let bigImg = document.createElement('img')
    bigImg.src = require('../images/big.jpeg')
    document.body.appendChild(bigImg)

    修改 webpack.config.js 代码

    module.exports = {
    // ...
        module: {
            rules: [
                // ...
                {
                // 图片格式正则
                    test: /.(png|jpe?g|gif|svg)(?.*)?$/,
                    use: [
                      {
                        loader: 'url-loader',
                        // 配置 url-loader 的可选项
                        options: {
                        // 限制 图片大小 10000B,小于限制会将图片转换为 base64格式
                          limit: 10000,
                        // 超出限制,创建的文件格式
                        // build/images/[图片名].[hash].[图片格式]
                          name: 'images/[name].[hash].[ext]'
                       }
                      }
                    ]
                }
            ]
        }
      }

    运行 npm run start,打包成功

    可以发现大的图片被单独提取了出来,小的图片打包进了 bundle.js 中。

    在浏览器中打开 HTML 文件,发现小图确实显示出来了(小图片实际上转化为base64位格式了),但是却没有看到大图,打开开发者工具栏,可以发现我们大图的图片路径是有问题的,所以我们又要修改 webpack.config.js 代码了。

    module.exports = {
        entry:  './app/index.js', // 入口文件
        output: {
          path: path.resolve(__dirname, 'build'), // 必须使用绝对地址,输出文件夹
          filename: "bundle.js", // 打包后输出文件的文件名
          publicPath: 'build/' // 知道如何寻找资源
        }
        // ...
      }

    重新编译下,就OK啦

    处理 CSS 文件

    添加 styles 文件夹,新增 addImage.css 文件,然后在该文件中新增代码

    使用 css-loader 和 style-loader 库。前者可以让 CSS 文件也支持 import,并且会解析 CSS 文件,后者可以将解析出来的 CSS 通过标签的形式插入到 HTML 中,所以后面依赖前者。

    npm i --save-dev css-loader style-loader

    addImage.js 文件中引入css文件

    import '../styles/addImage.css'

    修改 webpack.config.js 代码

    module.exports = {
    // ...
        module: {
          rules: [
            {
                test: /.css$/,
                use: ['style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true
                        }
                    }
                ]
            },
          ]
        }
      }

    运行下 npm run start,然后刷新页面,可以发现图片被正确的加上了边框,看一下 HTML 的文件结构

    可以看到,我们在 addImage.css 文件中写的代码被加入到了 style 标签中,并且因为我们开启了 CSS 模块化的选项,所以 .test 被转成了唯一的哈希值,这样就解决了 CSS 的变量名重复问题。

    但是将 CSS 代码整合进 JS 文件也是有弊端的,大量的 CSS 代码会造成 JS 文件的大小变大,操作 DOM 也会造成性能上的问题,所以接下来我们将使用 extract-text-webpack-plugin 插件将 CSS 文件打包为一个单独文件

    npm i --save-dev extract-text-webpack-plugin

    注意:如果是webpack4+ 

    npm install extract-text-webpack-plugin@next

    否则报错

    修改 webpack.config.js 代码

    const ExtractTextPlugin = require("extract-text-webpack-plugin")
    
    module.exports = {
    // ....
        module: {
          rules: [
            {
              test: /.css$/,
              // 写法和之前基本一致
              loader: ExtractTextPlugin.extract({
              // 必须这样写,否则会报错
                    fallback: 'style-loader',
                    use: [{
                        loader: 'css-loader',
                        options: { 
                            modules: true
                        }
                    }]
                })
            ]
            }
          ]
        },
        // 插件列表
        plugins: [
        // 输出的文件路径
          new ExtractTextPlugin("css/[name].[hash].css")
        ]
      }

    运行下 npm run start,可以发现 CSS 文件被单独打包出来了 

    这时候我们看到build文件夹里面多出了一个新的css文件夹。但是我们发现css文件并没有自动引入到html中

    于是,需要安装新的插件

    npm install html-webpack-plugin --save-dev

    修改 webpack.config.js 代码

    // 自带的库
    const path = require('path')
    const ExtractTextPlugin = require("extract-text-webpack-plugin")
    const HtmlWebpackPlugin = require("html-webpack-plugin")
    
    module.exports = {
        entry:  './app/index.js', // 入口文件
        output: {
          path: path.join(__dirname, 'dist'), // 必须使用绝对地址,输出文件夹(打包后的文件存放的地方)
          //__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录。
          filename: '[name].[chunkhash].js',// 打包后输出文件的文件名
          publicPath: './' // 知道如何寻找资源
        },
        module: {
            rules: [
                {
                // js 文件才使用 babel
                    test: /.js$/,
                 // 使用哪个 loader
                    use: 'babel-loader',
                // 不包括路径
                    exclude: /node_modules/
                },
                {
                // 图片格式正则
                    test: /.(png|jpe?g|gif|svg)(?.*)?$/,
                    use: [
                      {
                        loader: 'url-loader',
                        // 配置 url-loader 的可选项
                        options: {
                        // 限制 图片大小 10000B,小于限制会将图片转换为 base64格式
                          limit: 10000,
                        // 超出限制,创建的文件格式
                        // build/images/[图片名].[hash].[图片格式]
                          name: 'images/[name].[hash].[ext]'
                       }
                      }
                    ]
                },
                {
                    test: /.css$/,
                    loader: ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: [{
                            loader: 'css-loader',
                            options: {
                                modules: true
                            }
                        }]
                    })
                },
            ]
        },
        // 插件列表
        plugins: [
        // 输出的文件路径
          new ExtractTextPlugin("css/[name].[hash].css"),
    
          // 我们这里将之前的 HTML 文件当做模板
          // 注意在之前 HTML 文件中请务必删除之前引入的 JS 文件
          new HtmlWebpackPlugin({
            template: 'index.html'
          })
        ]
    }

    执行 build 操作会发现同时生成了 HTML 文件,并且已经自动引入了css和 JS 文件 

     打包之后的目录的文件夹结构如图 

     源码地址:https://github.com/zuobaiquan/webpack/tree/master/my_webpck

    参考链接地址:https://segmentfault.com/a/1190000012718374

  • 相关阅读:
    数据库异常处理记录
    FINEMVC重定向和显示合计
    有意思的文章的链接
    oralce 创建用户和权限
    FINEUI(MVC) grid 双击弹窗功能
    FINEUI(MVC)布局问题记录
    通过判断cookie过期方式向Memcached中添加,取出数据(Java)
    通过数组方式向Oracle大批量插入数据(10万条11秒)
    Python基础学习13--面向对象
    Python基础学习12--变量作用域
  • 原文地址:https://www.cnblogs.com/zuobaiquan01/p/9249724.html
Copyright © 2011-2022 走看看