美文网首页
webpack入门三

webpack入门三

作者: 焚心123 | 来源:发表于2021-04-18 11:33 被阅读0次
    • 这章你将学习到使用图片,特殊字体等怎么在页面上进行显示,还有多个入口文件,怎么输出

    在前面的两章中,我们每次打包,之前的打包文件还在,想要不在的话,需要我们手动进行删除,但是怎么让我们每次打包的时候,自动的将其前面打包过的文件自动清除

    npm install clean-webpack-plugin -D

    • kfc.config.js
     const { CleanWebpackPlugin } = require("clean-webpack-plugin");
     ....
      plugins:[//todo 不同的插件,可以帮助我们处理不同的事
                new HtmlWebpackPlugin({
                    template:'./src/index.html'
                }),
                new MiniCssExtractPlugin({
                    filename: "css/[name].css"
                }),
                new CleanWebpackPlugin()//直接加入这个就好啦
            ]
    
    1、在js中使用dom添加图片,怎么在页面中显示
    • 首先在我们的src下新加入一张图片bj.jpg
    • 在index.js中加载一张图片,加载成功添加到app后面
    import bgImg from './bj.jpg';
    const img = new Image();
    img.src = bgImg;
    img.onload = ()=>{
        app.append(img);
    }
    img.onerror = ()=>{
        console.log('图片加载错误');
    }
    
    • 此时进行打包,文件还是延续之前的webpack入门一,二的那个文件


      image.png
    • 此时显示的是乱码,该怎么办呢?

    • 使用file-loader进行解析我们的图片格式

    npm install file-loader -D

    • 在kfc.config.js中进行配置
                    {
                        test:/\.(png|jpg|gif|jpeg|webp)$/,
                        use:{
                            loader:'file-loader',
                            options:{
                                name:'[name]_[hash:6].[ext]',//* hash:6 表示hash值截取前6位,ext表示图片结尾是.png输出就是.png,是.jpg输出就是.jpg
                                outputPath:'image',//* 输出的文件名
                                publicPath:'../image'//* 这是配置公共的路径,目前不需要
                            }
                        }
                    }
    
    • 此时进行打包,就会在页面上显示我们加载的图片了,我们将index.js中加载的图片改为css的背景图片,进行打包,会发现它会将我们的图片都进行base64的转化,但是小的图片一般转成base64会好一点,但是大的图片也转换的话,那么生成的base64会很长而且也不利于我们页面的性能,此时我们使用iconfont中的特殊字体的话,也是加载不出来的,我们要进行使用另一个url-loader进行解析,这个loader是在file-loader的基础上进行的封装,他可以设置图片大于多少的时候不用进行base64转换,还可以解析特殊字体,下面让我们试一试吧

    npm install url-loader -D

    • 先打开iconfont官网选择特殊字体进行本地下载,之后将里面的文件放到src文件夹下


      image.png
    • 在index.scss进行引入

    @font-face {
        font-family: 'webfont';
        font-display: swap;
        src: url('webfont.eot'); /* IE9 */
        src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
        url('webfont.woff2') format('woff2'),
        url('webfont.woff') format('woff'), /* chrome、firefox */
        url('webfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
        url('webfont.svg#webfont') format('svg'); /* iOS 4.1- */
    }
    
        #app{
            width: 400px;
            height: 400px;
            // background: orange;
            font-family: 'webfont' !important;
            background: url('./bj.jpg') 30% 20%  no-repeat;
            .head{
                width: 40px;
                height: 40px;
                // background: red;
            }
            img{
                width: 400px;
                height: 300px;
            }
        }
    
    • 在src/index.html
        <div id="app">
            <p class="head"></p>
            <p>英雄不问出路,流氓不看岁数。</p>
        </div>
    
    • kfc.config.js中
    {
                        test:/\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,
                        use:{
                            loader:'url-loader',
                            options:{
                                limit:1020*100,//* 当图片大小超过这个指定的大小,不会再进行base64的转义
                                name:'[name]_[hash:6].[ext]',//* hash:6 表示hash值截取前6位,ext表示图片结尾是.png输出就是.png,是.jpg输出就是.jpg
                                outputPath:'image',//* 输出的文件名
                                publicPath:'../image'//* 这是配置公共的路径,目前不需要
                            }
                        }
                    }
    
    • 进行打包,查看效果


      image.png
    • 当前我使用的图片是96kb,1024是1kb,1024100是100kb,设置为102410就是10kb,大于10kb就不会进行base64转义
    image.png
    image.png
    • 简单的说下占位符(指纹策略)

    [name] 输入是什么名,输出就是什么名
    [hash] 输出的就是有hash值的,这个是全局的,要是有多个入口文件的话,那么生成的hash值都是相同的,一个文件修改的话,所有文件的hash值都会进行变化,这样的话,区分不出来文件
    [chunkhash] 就是一个入口文件就是一个chunks,他们的chunks不同可以根据这个进行区分,但是如果这个入口文件中引入了一个模块,那么模块更新的话,那这个chunkhash的值变不变化呢?答案是肯定会变化的,那么如果这个index.js文件进行修改,里面引入的模块会不会变呢,也是会变化的
    [contenthash] 这个是内容hash,如果修改index.js,里面引入的模块,此时不会发生改变,如果模块变了,这个index.js肯定也是会变的,包含的关系
    [hash:6] 意思是hash值截取前6位

    2、如果有多个入口文件我们怎么操作呢?
    • 这是目录结构


      image.png
    • 在kfc.config.js中


      image.png
      image.png
    • 运行打包可以看到


      image.png
    • 不同的文件只引入自己的文件,如index.html中不会将list.js文件进行引入,list.html中不会将index.html中引入的文件在引入自己的文件中

    • 但是上面的写法都是我们手动完成的,要是有十个百个,我们难道要一个一个的进行手动的写吗,那肯定是不行的,有个glob插件,可以让我们读取到文件,然后动态的生成

    npm install glob -D

    • 图下方是核心代码,进行封装


      image.png
    • 整体的kfc.config.js

        /**
         * ! 使用webpack中自带的loader以及插件
         * ! 自定义的loader文件在kfc.config-1.js文件中
         * ! html-webpack-plugin 通过HtmlWebpackPlugin这个插件,可以将index.html进行复制,打包后会将打包的js文件等自动的引入
         * ! mini-css-extract-plugin 为每个引入css的js文件创建一个css文件
         * ! 使用sass-loader,css-loader,style-loader进行.scss文件的格式化
         * ! 使用URL-loader处理文件,字体,图片,在file-loader基础上进行了封装,可以限制多大的图片不用转base64格式
         * ! 使用file-loader也可以处理文件,字体,图片,但是当有的图片可以进行转为base64格式,不可控制
         * ! 使用clean-webpack-plugin,每次打包都会把之前打包的文件进行清除
         * ! glob 读取文件
         */
        const glob = require('glob');
        const { CleanWebpackPlugin } = require("clean-webpack-plugin");
        const path = require('path');
        //todo 通过HtmlWebpackPlugin这个插件,可以将index.html进行复制,打包后会将打包的js文件等自动的引入
        const HtmlWebpackPlugin = require('html-webpack-plugin');
    
        // todo 为每个引入css的js文件创建一个css文件
        const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    
        const setMap = ()=>{
            const entry = {};
            const HtmlWebpackPlugin1 = [];
    
            const entryFile = glob.sync(path.join(__dirname,'/src/*/index.js'));
            entryFile.map(item=>{
                const key = item.match(/src\/(.*)\/index\.js$/);
                const pageName = key[1];
                entry[pageName] = item;
                console.log(entry);
                HtmlWebpackPlugin1.push(new HtmlWebpackPlugin({
                    template:path.join(__dirname,`src/${pageName}/index.html`),
                    filename:`${pageName}/${pageName}.html`,
                    chunks:[pageName]
                }))
               
            })
            console.log(entry);
             console.log(HtmlWebpackPlugin1[0].options.chunks);
             console.log(HtmlWebpackPlugin1[1].options.chunks);
            return {
                entry,
                HtmlWebpackPlugin1
            }
        }
        const { entry, HtmlWebpackPlugin1 } = setMap();
    
        module.exports = {
            entry,
            // entry:'./src/index.js',//入口文件(单文件入口)
            // entry:{//todo 多文件入口
            //     index:'./src/index/index.js',
            //     list:'./src/list/index.js'
            //     // main:'./src/main.js'
            // },
            output:{
                path:path.resolve(__dirname,'./build'),//todo 打包后存放的文件名
                filename:'[name]/[name]_[chunkhash:6].js'//todo 打包后的文件名,单文件'build.js'直接写,多文件[name],入口文件名是啥,打包后还是啥
            },
            //todo 当前的模式,none 不做任何的处理 development开发环境做了相应的处理,方便调试,production生产环境会启动相应的插件
            mode:'development',
           
            module:{//todo 模块,一般可以将我们的scss,less,.vue等进行loader解析,在输出
                rules:[//todo 规则
                    {//todo 每个模块都是独立的
                        test:/\.css$/,//todo .css结尾的文件进行解析
                        use:['style-loader','css-loader']//todo 自后往前的顺序,不能写错了,还可以单独的配置loader
                    },
                   
                    {//todo 每个模块都是独立的 
                        test:/\.scss$/,//todo .css结尾的文件进行解析
                        use:[
                            // 'style-loader',// 将 JS 字符串生成为 style 节点
                            MiniCssExtractPlugin.loader,
                            'css-loader',// 将 CSS 转化成 CommonJS 模块
                            'postcss-loader',
                            'sass-loader'// 将 Sass 编译成 CSS,默认使用 Node Sass
                        ]//todo 自后往前的顺序,不能写错了,还可以单独的配置loader
                    },
                    {
                        test:/\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,
                        use:{
                            loader:'url-loader',
                            options:{
                                limit:1020*10,//* 当图片大小超过这个指定的大小,不会再进行base64的转义
                                name:'[name]_[hash:6].[ext]',//* hash:6 表示hash值截取前6位,ext表示图片结尾是.png输出就是.png,是.jpg输出就是.jpg
                                outputPath:'image',//* 输出的文件名
                                publicPath:'../image'//* 这是配置公共的路径,目前不需要
                            }
                        }
                    }
                ]
            },
            plugins:[//todo 不同的插件,可以帮助我们处理不同的事
                ...HtmlWebpackPlugin1,
                // new HtmlWebpackPlugin({
                //     template:'./src/index/index.html',
                //     filename:'index/index.html',
                //     chunks:['index']//! 进行区分,不同的文件夹只能引入同文件夹中的文件,不能index.html中引入了,list.html中也进行引入了,所以要区分
                // }),
                // new HtmlWebpackPlugin({
                //     template:'./src/list/index.html',
                //     filename:'list/list.html',
                //     chunks:['list']
                // }),
                new MiniCssExtractPlugin({
                    filename: "css/[name].css"
                }),
                new CleanWebpackPlugin()
            ]
        }
    
    • 注意:要是没打包成功,一定要看报错的信息,可能是你的.scss文件中的特殊字体导致的错误或者是其他的,记得看报错信息进行排查

    相关文章

      网友评论

          本文标题:webpack入门三

          本文链接:https://www.haomeiwen.com/subject/zjyelltx.html