webpack3.0学习笔记(二)

—— 与loader的爱恨情仇

目录一览

webpack3.0学习笔记(一)
webpack3.0学习笔记(二)
webpack3.0学习笔记(三)

项目源码地址


前情概要

webpack 学习笔记(一)中,对 css 相关的 loader 均有涉猎,所以本篇涉及到的 loader 仅包括:html-loader,url-loader,file-loader,image-webpack-loader 等上篇遗漏几个的使用情况。


以 html-loader 为引

html-loader 顾名思义的是引用时解析 .html 文件的加载器。

先把要用的几个 loader 一次安装:

yarn add -D extract-loader file-loader html-loader url-loader image-webpack-loader

或使用NPM进行安装:

npm i -D extract-loader file-loader html-loader url-loader image-webpack-loader

项目目录结构的:


webpack3.0学习笔记(二)_第1张图片
项目目录结构

webpack.config.js 配置如下:

module.exports = {
    entry: {
        html: path.resolve(__dirname,'src/index.html'),
    },
    output: {
        filename: 'js/[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module:{
        rules: [          
            {
                test: /\.html$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]'
                        }
                    },
                    'extract-loader',
                    {
                        loader: 'html-loader',
                        options: {
                            attrs: ["img:src", "link:href"]
                        }
                    }
                ],
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name]-[hash:6].[ext]',
                            outputPath: 'css/'
                        }
                    },
                    "extract-loader",
                    {
                        loader: "css-loader",
                    }
                ]
            },
            {
                test: /\.(jpe?g|png|gif|svg)$/i,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name]-[hash:6].[ext]',
                            outputPath: 'image/'
                        }
                    },
                ]
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),        
    ]
};

index.html 内容如下:




    
    
    
    this is webpack loader test
    
    


    
    
  1. 通过 entry 中配置页面地址方式(这个方法很不好,后面会讲到这个问题)引入 html 文件,当然也可以配置一个入口 js 文件引用这个 html 页面也可以。
  2. 通过 html-loader 的配置项 attrs 获取页面内所有 img 标签的 srclink 标签的 href 地址,将图片和 css 等静态资源就都被引入 webpack 打包流程。
  3. css 匹配规则里使用了 extract-loader 目的是将 css 文件进行分离,再通过 file-loader 将其输出至打包后的对应目录。
  4. 图片及字体等资源文件均可通过 extract-loader + file-loader 在优化后进行分离生成本地文件的方式操作。
  5. 当然图片也可以使用 url-loader 进行处理,该 loader 是在 file-loader 上进行了扩展,增加 limit 配置,使得小于所设阈值的文件可以 Data URL 的形式内联,以图片为例则是转化为 Base64 的格式,超出阈值的则继续生成文件,转化后 html 文件会相应变大,何时内联图片请多斟酌。在使用 url-loader 前还可使用 image-webpack-loader 对图片进行压缩处理。
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
    {
        loader: 'url-loader',
        options: {
            name: '[name]-[hash:6].[ext]',
            outputPath: 'image/',
            limit: 8192
        }
    },
    'image-webpack-loader'
]
webpack3.0学习笔记(二)_第2张图片
图片转Base64
  1. 到现在还没有完,css和图片优化输出完这些静态资源文件后会生成其新路径,此时已在 html-loader那更新了对应地址,然后利用 extract-loader file-loader 将 'index.html' 分离出来。
...



.yintama {width: 440px;height: 200px;background:url(image/yintama-20a729.gif)} ...
webpack3.0学习笔记(二)_第3张图片
图片路径

注意:
html 中的图片地址从 ./image/shana.jpg 被替换为 image/shana-423df3.jpg,而 css 中地址由 ../image/yintama.gif 替换为 image/yintama-20a729.gifhtml 引用图片路径正常,而 css 文件引用图片时路径则报错了,正确地址应该为 ../image/yintama-20a729.gif

  • 通过查看项目github发现这个路径生成规则是 file-loader 既定的逻辑。
    尝试使用 loaderuseRelativePath 配置,引用时的相对路径是保留了,但是生成图片的路径却出现问题,../image/yintama.gif图片层级是上一级,生成图片的路径 pathdist 目录,yintama.gif 这张图片被放置到项目根目录。
  • 相对路径这条路是走不通了,现在有两个办法:
    • 一是将 html 文件也放至 html 目录内,保持 css html 文件的目录层级相同,再设置 publicPath../../dist/ 保证引用目录的正确。(但是这样弊端很明显,一旦目录层级不统一依然会产生错误。很想把作者按在的地上摩擦,为何不能生成新路径时智能点)。
    • 二是将图片生成地址全换成绝对路径,在生成环境下配置 publicPath 为CDN路径,而开发环境下设置为 http://localhost:8080/dist/,开发环境打包也可以配置为以上地址,开启一个本地服务器即可访问测试。
const url = require('url')

module.exports = {
    ...
    module:{
        rules: [
            ...
            {
                test: /\.(jpe?g|png|gif|svg)$/i,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            name: '[name]-[hash:6].[ext]',
                            outputPath: 'image/',
                            limit: 1,
                            publicPath: url.format({
                                hostname:'localhost',
                                protocol:'http:',
                                port:8080,
                                pathname:'/dist/'
                            })
                        }
                    }
                ]
            }
        ]
    },
    devServer: {
        publicPath: '/dist/',
        historyApiFallback: true,
        openPage: 'dist/',
        inline: true,
        port: 8080,
        hot: true
    }
}
...

热替换处配置进行了修改,去除了 contentBase: './dist', 的配置,会导致页面URL丢失 dist 这层路径,引用绝对地址的资源无法找到,故改为以上配置。

html-loader 使用中发现 js 优化完不能自动引入 html 页面。(当然可以在页面中自己手动引入,但是文件生成 hash 时就杯具了。也可以使用 html-loaderattrs 属性获取 script:src 获取地址,但是这样 entry 配置中的 chunk 便显得毫无意义,这种做法仅仅是将将 webpack 当做一个压缩工具,而非模块化打包工具。)


总结

通过对 html-loaderloader 的学习使用了解了如何处理其他静态资源文件的方法,也解决了笔记(一)中当一个页面如果引用多个 css 文件,该如何保留其原有 css 数量而不进行合并,通过 extra-loader + file-loader 进行分离操作。
然而过程中也遇到了困难,如何处理图片的路径问题,以及使用 html-loader 要怎么自动引入 js 文件的问题。
下章尝试更方便的形式构建页面并且自动引入静态资源和 js


尾巴

不得不吐槽 webpack 的官网阅读起来真的很扎心,搜索一下跳转到英文页面,翻译里也大片英文,指引看起来也各种调戏,原先没有中文站的时候 巨巨 们都是怎么坚持下来的,顶礼膜拜!

你可能感兴趣的:(webpack3.0学习笔记(二))