【webpack】2. loader---动态加载css样式,文件,数据

webpack学习

【webpack】1.快速入门
【webpack】2.webpack核心–loader
【webpack】3. 将入口html也打包
【webpack】4. webpack-dev-server思考
【webpack】5.开发和生产模式的配置加载

webpack loader

webpack本身就能理解js,所以可以随意import不需要loader,但是如果import的是其他文件比如css,则不能理解,需要告诉它css怎么加载,这就是loader的职责。css用css-loader和style-loader。loader是webpack的核心

1. 准备工作:创建项目

为了方便也为了重新复习下webpack配置,重新新建个文件夹, 在mac terminal中输入

mkdir loader .  //新建
cd loader
npm init -y
npm install webpack webpack-cli --save

在这里插入图片描述

  1. 新建一个新的index.html
  2. 修改package.json里的script配置
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "pack": "node_modules/.bin/webpack --watch"
  },
  1. 新建一个js文件夹放js文件
  2. 新建webpack.config.js如下
module.exports={
    entry:'./js/index.js',//入口文件
    output:{//出口
        filename:'pack.js',//文件名
        path:__dirname + '/dist'
    }
}

现在目录如下
在这里插入图片描述
之前每次修改js里的文件都要重新打包,这里可以对package.json进行修改,实现监听变动并自动打包,package.json修改如下,后面加个–watch即可,只要项目里的文件发生变化就重新打包

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "pack": "node_modules/.bin/webpack --watch"
  },

npm run pack打包
打包完成后的pack.js在./dist目录下,记得要在index.html中引入打包后的pack.js文件, 在浏览器中打开index.html即可

    <body>
        <script src="./dist/pack.js"></script>
    </body>

在js文件夹下创建base.js,新建一个css文件夹放base.css,index.js里想要import base.js和base.css.base.js没问题,base.css就不行,因为webpack本身就能理解js,所以可以随意import不需要loader,但是如果import的是其他文件比如css,则不能理解,需要告诉它css怎么加载,这就是loader的职责。css用css-loader和style-loader

2. 使用css相关loader

先npm引入这两个loader包

npm install css-loader style-loader --save

再修改配置文件webpack.config.js,备注中有解释

module.exports={
	mode: 'development',//开发模式
    entry:'./js/index.js',//入口文件
    output:{//出口
        filename:'pack.js',//文件名
        path:__dirname + '/dist'//当前目录下
    },
    module: {
        rules: [
            {
                test: /\.css$/i,//正则  意思是只要以css结尾的文件就遵循这个规则,i表示不区分大小写
                use:['style-loader', 'css-loader']//css-loader是用来专门解析css语法,最主要作用就是把文件内容变成字符串传递下去,style-loader把css-loader解析好的字符串插入到html的style标签里。顺序很重要从右往左
            }
        ]
    }
}

这时候index.js里就可以引入css文件了

import '../css/base.css'
console.log('8')
  • 如果引入两个css文件,一个设置背景色为红色,一个为黑色,那么第二个import的优先级更高,覆盖第一个。这就和写再html的style标签里一样
  • loader就是在模块导入资源的时候会分析一下是不是js,如果不是js怎么能转化成js理解的方式最后穿插到html里面,有一二百个loader

css-loader是用来专门解析css语法,最主要作用就是把文件内容变成字符串传递下去
style-loader把css-loader解析好的字符串插入到html的style标签里

标明css来源

但这样也会出现问题,比如在base.js里设置body的背景色,在more.css里设置border样式,在index.js里引入这两个样式,打包运行打开index.html会发现,右下角仅仅能看到style, 看不出是哪个文件设置里背景色,哪个设置了border
在这里插入图片描述
解决办法就是修改配置文件webpack.config.js里的module的rules,[]里写成对象形式

        rules: [
            {
                test: /\.css$/,//正则表达式,只要以css结尾的文件遵循这个规则
                use:[
                    {
                        loader:'style-loader'
                    }, 
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true,
                        }
                    }
                ]//style-loader就是把这个文件放到html的<style>里
            }
        ]

这样更改之后再重新npm run pack后,得到结果如下
在这里插入图片描述
就标明了样式来源

3. 文件loader

如果import的是图片而不是css文件,那要怎么处理,
在项目目录下新建一个文件夹image,里面放入一张图片
想在index.js中直接导入一个图片,就像js一样
index.js

import '../css/base.css'
import '../css/more.css'
import imgsrc from '../img/timg.jpeg'//图片导入,像js文件一样
console.log('8')
let img = document.createElement('img')
img.src = imgsrc
document.body.appendChild(img)

打包运行后报错如下
在这里插入图片描述
因为图片拿过来是二进制的数据,原生只能读懂js,所以不认识

  • 先安装file-loader
npm i file-loader --save
  • 修改webpack.config.js里的module里的rules
        rules: [
            {
                test: /\.css$/,//正则表达式,只要以css结尾的文件遵循这个规则
                use:[
                    {
                        loader:'style-loader'
                    }, 
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true,
                        }
                    }
                ]//style-loader就是把这个文件放到html的<style>里
            },
            {
                test: /\.(jpg|jpeg|png|gif)/i,//结尾是这些的文件遵循这个规则
                use: [
                    {
                    loader: 'file-loader'
                    }
                ]
            }
        ]

再打包运行,不报错了,但就是打开网页图片不显示出来
在这里插入图片描述
打开控制台查看,文件名有的
在这里插入图片描述
再查看下存放打包文件的dist目录
在这里插入图片描述
看出来图片文件名一致,只不过路径不对,少了dist
加上./dist就发现可以显示了,因为打包后的图片在dist目录下
在这里插入图片描述
所以改写webpack.config.js,加个options

            {
                test: /\.(jpg|jpeg|png|gif)$/i,
                use: [
                    {
                    loader: 'file-loader',
                    options: {
                        publicPath: './dist/'
                    }
                    }
                ]
            }

再打包运行就可以了
为了方法,可以统一指定publicPath,如果以后有其他loader插件要看公开的地址,也就是公开文件的地址,就可以一起在output指定

module.exports={
    mode: 'development',
    entry: './js/index.js',
    output: {//出口
        filename:'pack.js',
        path:__dirname + '/dist',
        publicPath: './dist/'//指定公开目录
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use:[
                    {
                        loader:'style-loader'
                    }, 
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true,
                        }
                    }
                ]
            },
            {
                test: /\.(jpg|jpeg|png|gif)$/i,
                use: [
                    {
                    loader: 'file-loader'
                    }
                ]
            }
        ]
    }
}

虽然一般不在js里import图片,但css的background里经常需要图片,这也需要对file-loader的配置,比如更改base.css如下

body {
    background: url('../img/timg.jpeg')
}

把index.js中之前对图片import删掉(避免干扰),把webpack.config.js里对file-loader的配置注释掉,报错
在这里插入图片描述
加上file-loader配置后打包运行,得到效果如下(每次更改package.json都要重新npm run pack,–watch只作用于其他文件
在这里插入图片描述
所以file-loader真的很必要,html中加载的都是打包目录里的文件,图片和字体都可以

4. 动态加载数据

修改index.html,在body中加三个a标签(为了看得清楚,我把之前background的图片url改成背景色了)

    <body>
        <nav>
            <a href="#hello">hello</a>
            <a href="#world">world</a>
            <a href="#hahaha">hahaha</a>
        </nav>
        <script src="./dist/pack.js"></script>
    </body>

显示如下
在这里插入图片描述
现在这个是写死的,如果想动态更改必须得修改代码,为了避免如此,可以将其存成一个数据,json格式,在目录下创建nav.json

[
    {
        "text": "hello",
        "url": "#hello"
    },
    {
        "text": "world",
        "url": "#world"
    },
    {
        "text":"hahaha",
        "url":"#hahaha"
    },
    {
        "text":"hehehe",
        "url":"#hehehe"
    }
]

修改 index.js

import list from '../nav.json'
const nav = document.querySelector('nav')
list.forEach(element => {
    let a = document.createElement('a')
    a.innerText = element.text
    a.href = element.url
    nav.appendChild(a)
})

把index.html中之前创建的写死的a标签删掉,再保存,打开,有效
在这里插入图片描述
import json数据不需要特意去配置个loader,webpack可以理解

5. 练习 导入sass

webpack的核心就是loader,有了loader才可以解析各式各样的文件。就像vue文件,把js,html和css都写在一起。正因为有了vue-loader,webpack构建的时候才能读懂。
想到平时写样式会用到.scss文件,所以这里再加一个对scss文件的配置。需要安装两个 node-sass sass-laoder

npm i node-sass sass-loader --save

安装完在webpack.config.js的module的rules数组里加一个对象

{
            test: /\.scss$/i,
            use: [
                {
                    loader: 'style-loader'
                },
                {
                    loader: 'css-loader'
                },
                {
                    loader: 'sass-loader'
                }
            ]
        }

从右向左执行,所以先将sass转化为css,再把css转化为字符串,再把字符串插入到html的style标签内
这时候,再在index.js里import '…/css/test.scss’,就不会报错了

猜你喜欢

转载自blog.csdn.net/qq_33712668/article/details/98094896