手记

Webpack 4.X 从入门到精通 - module

概念

webpack中任何一个东西都称为模块,js就不用说了。一个css文件,一张图片、一个less文件都是一个模块,都能用导入模块的语法(commonjsrequireES6import)导入进来。webpack自身只能读懂js类型的文件,其它的都不认识。但是webpack却能编译打包其它类型的文件,像ES6JSXlesstypeScript等,甚至cssimages也是Ok的,而想要编译打包这些文件就需要借助loader

loader就像是一个翻译员,浏览器不是不认识这些东西么?那好交给loader来办,它能把这些东西都翻译成浏览器认识的语言。loader描述了webpack如何处理非js模块,而这些模块想要打包loader必不可少,所以它在webpack里显得异常重要。loader跟插件一样都是模块,想要用它需要先安装它,使用的时候把它放在module.rules参数里,rules翻译过来的意思就是规则,所以也可以认为loader就是一个用来处理不同文件的规则

文件目录

这节课需要用到图片跟样式,所以我要按传统的目录结构来创建目录,目录如下
结构目录

处理CSS

所需loader

style-loader   //把处理完的css放到style标签里css-loader     //处理css

安装

npm i style-loader css-loader -D

index.css文件内容如下:

#box{    width: 800px;    height: 500px;    border: 5px solid #999;    color: #00f;    background: green;}

index.js文件内容如下:

import '../css/index.css';  //两个点是找上级目录

通过前面的课程大家要明白,webpack的入口文件是index.js,如果要处理其它类型的文件,就需要在入口文件里把其它类型的文件导入进来,而在webpack中所有文件都是模块,所以可以使用require或者import导入其它文件

package.json文件内容如下:

{  "name": "webpack-demo",  "version": "1.0.0",  "description": "",  "main": "webpack.config.js",  "scripts": {    "build": "webpack --mode production",    "dev": "webpack-dev-server --mode development"  },  "keywords": [],  "author": "",  "license": "ISC",  "devDependencies": {    "css-loader": "^1.0.0",    "html-webpack-plugin": "^3.2.0",    "style-loader": "^0.21.0",    "webpack": "^4.16.3",    "webpack-cli": "^3.1.0",    "webpack-dev-server": "^3.1.5"  }}

webpack.package.json文件内容如下:

const path=require('path');const HtmlWebpackPlugin=require('html-webpack-plugin');module.exports={    entry:{        index:'./src/js/index.js',    },    output:{        path:path.resolve(__dirname,'dist'),        filename:'[name].bundle.js'    },    plugins:[        new HtmlWebpackPlugin({            title:'陈学辉',            template:'./src/template.html',            filename:'index.html',        })    ],    devServer:{        host:'localhost',        port:1573,        open:true,    },    module:{        rules:[            {                test:/\.css$/,  //以点开始css结尾的文件                use:['style-loader','css-loader']   //顺序不能搞错            }        ]    },}

执行命令npm run dev后就可以看到效果

说明

  1. rules里的数据类型为对象,每一个loader都是一个对象

  2. test表示loader要处理什么类型的文件,这里用了一个正则去匹配文件类型

  3. use表示要使用哪个loader,它的值是个数组,loader的使用顺序是从后往前

  4. 这个loader的意思为,在入口文件里找到.css类型的文件,先拿css-loader去处理成浏览器认识的css,再拿style-loader把处理后的css放在页面的style标签里

css-loader其它配置:https://www.webpackjs.com/loaders/css-loader/
style-loader其它配置:https://www.webpackjs.com/loaders/style-loader/

单独提取CSS

执行命令npm run build后,在dist目录里只有两个文件,一个index.bundle.js一个index.html文件,并没有css文件,同时打开index.html源码后也没有发现有css的内容。这是因为style-loader的作用,它把css一同打包到了js文件里,js文件在能过DOM动态创建style标签并添加到页面里。所以css的内容已经放到了index.bundle.js里。

这种形式只有当文件内容不多的时候可以使用,如果CSS的内容以及JS的内容非常的多,把两块都打包到一个文件里就会增加文件的体积,用户打开页面的时候下载速度会受影响,同减肥影响用户体验。这就需要把CSS文件单独拎出来,那需要一个插件来配合loader才能完成

mini-css-extract-plugin

webpack版本需要4.3以上,低版本请使用extract-text-webpack-plugin
使用步骤:
1、安装

npm i mini-css-extract-plugin -D

2、在webpack.config.js里引入模块

const MiniCssExtractPlugin=require("mini-css-extract-plugin");

3、写入plugins

plugins:[    new HtmlWebpackPlugin({        title:'陈学辉',        template:'./src/template.html',        filename:'index.html',    }),    new MiniCssExtractPlugin({        filename:'css/index.css'    //文件目录会放入output.path里    }),]

4、写入loader

module:{    rules:[        {            test:/\.css$/,            use:[MiniCssExtractPlugin.loader,"css-loader"]  //代替style-loader        }    ]}

执行命令npm run build后可以看到dist目录里已经多了一个css文件夹,这个文件夹里放了一个index.css文件。打开index.html源码看到css文件已经通过link标签引入,这些功能都是mini-css-extract-plugin所做的

mini-css-extract-plugin其它配置:https://github.com/webpack-contrib/mini-css-extract-plugin

处理图片

所需loader

file-loader   //解析地址url-loader    //把图片地址解析成base64

安装

npm i file-loader url-loader -D

index.css文件内容如下:

#box{    width: 800px;    height: 500px;    border: 5px solid #999;    color: #00f;    /*background: green;*/    background: url(../images/img_01.jpg);  //背景改成了图片}

index.js文件内容如下:

import '../css/index.css';  //两个点是找上级目录

webpack.package.json文件内容如下:

const path=require('path');const HtmlWebpackPlugin=require('html-webpack-plugin');module.exports={    entry:{        index:'./src/js/index.js',    },    output:{        path:path.resolve(__dirname,'dist'),        filename:'[name].bundle.js'    },    plugins:[        new HtmlWebpackPlugin({            title:'陈学辉',            template:'./src/template.html',            filename:'index.html',        })    ],    devServer:{        host:'localhost',        port:1573,        open:true,    },    module:{        rules:[            {                test:/\.css$/,  //以点开始css结尾的文件                use:[                    //这是一个loader,如果loader需要给参数,就写成对象的形式                    {                        loader:MiniCssExtractPlugin.loader, //loader是哪个                        options:{   //所有的配置参数都要放在这个对象里面                            publicPath:'../'    //这个表示在css文件里但凡用到地址的地方在其前面加个目录'../',这个是为了能找到图片                        }                    },                    'css-loader'    //这个loader没有其它选项就直接写                ]            },            {                test:/\.(jpg|png|gif)$/,    //找到三种格式中的任意一种                use:['file-loader']            }        ]    },}

执行命令npm run dev后就可以看到效果

说明

  1. loader既可以写成字符串的形式,也可以写成对象的形式。如果这个loader需要给一些配置,那就需要写成对象的形式,所有的配置放到options

  2. 这里一定要注意第一个loaderuse属性,它里面放的是一个个loader,每个loader的值既可以是对象形式,又可以是字符串形式

file-loader其它配置:https://www.webpackjs.com/loaders/file-loader/

在HTML文件中使用图片

index.js文件内容如下:

import '../css/index.css';import img1 from '../images/img_01.jpg';import img2 from '../images/img_02.jpg';const loadImg=img=>{    const newImg=new Image();    newImg.onload=()=>document.body.appendChild(newImg);    newImg.src=img;};loadImg(img1);loadImg(img2);

webpack.package.json文件内容如下:

const path=require('path');const HtmlWebpackPlugin=require('html-webpack-plugin');const MiniCssExtractPlugin=require("mini-css-extract-plugin");module.exports={    entry:{        index:'./src/js/index.js',    },    output:{        path:path.resolve(__dirname,'dist'),        filename:'[name].bundle.js'    },    plugins:[        new HtmlWebpackPlugin({            title:'陈学辉',            template:'./src/template.html',            filename:'index.html',        }),        new MiniCssExtractPlugin({            filename:'css/index.css'        }),    ],    devServer:{        host:'localhost',        port:1573,        open:true,    },    module:{        rules:[            {                test:/\.css$/,                use:[                    {                        loader:MiniCssExtractPlugin.loader,                        options:{                            publicPath:'../'                        }                    },                    "css-loader"                ]            },            {                test:/\.(jpg|png|gif)$/,                //use:['file-loader']                use:[                    {                        loader:'url-loader',    //把图片转成base64                        options:{                            limit:50*1024,  //小于50k就会转成base64                            outputPath: 'images'                        }                    }                ]                //use:'url-loader?limit=50000&outputPath=images'    //loader的另一种写法,与get请求方式相同            }        ]    },}

执行命令npm run dev后就可以看到效果

说明

  1. url-loader的作用是把图片转成base64,它同样可以给配置参数

  2. limit的作用是小于这个值就会转base64

  3. 只用了url-loader,并没有用file-loader,说明url-loader里已经包含了file-loader的功能

  4. loader还可以写成地址的形式,与get的请求方式相同



0人推荐
随时随地看视频
慕课网APP