走进webpack基础分析

171 阅读3分钟

webpack

项目很小的时候我们可以考虑一个一个js css引入到html中,但是项目大的话这样搞,你懂的,会死人的...这个时候webpack就可以出场了,webpack除了编译文件的功能还有压缩代码等等功能

打包单页面

例子:验证是否识别es6的import关键字
在开始demo之前,先确认是否安装webpack,如果没有安装使用以下指令

npm i -g webpack webpack-cli
npm init -y //生成package.json文件
npm i jquery //引入jquery,方便验证es6的import

创建src文件夹,并在src文件夹下面创建index.js文件,并简单的写几行代码(暂时验证import)

import $ from 'jquery';
$(function () {
    $("body").css("background","#f40")
})

创建一个index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="src/index.js"></script>
    <!-- <script src="dist/main.js"></script> -->
</head>
<body>
    
</body>
</html>

此时我们运行在浏览器(open in Default browser)发现我们设置的body颜色并没有发生变化,此刻脑子一万只xxx飞过...,不用惊讶,基操...这就是上面提到的浏览器只认识js,并不认识import这鬼东西,此刻我们就需要借助webpack啦,那就看看webpack有多大的能耐吧!
首先我们创建webpack.config.js文件,很多人可能疑问为什么创建这个文件webpack就能找到,这里我还没研究到,嘻嘻

const path = require('path');
module.exports = {
    mode: "development",
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, "dist") ,//解析地址
        filename:"main.js"
    }
}

然后终端切换到项目目录控制台运行webpack,此刻会看到项目目录生成了dist文件夹下面并且增加了一个main.js文件。然后替换index.html的,你会发现浏览器运行的项目变成了淘宝红,没错,证明webpack真的把import编译成浏览器认识的东东。不要高兴的太早,这里简要的介绍下webpack.config.js配置文件:
const path = require('path') 这里使用了node的path模块,把绝对地址转换为相对地址
mode:模式,我们可以设置为生产还是开发模式,众所周知开发环境我们需要查看报错信息 源码 热更新等等,开发环境我们需要压缩代码 混淆代码等等,这个mode就是区分他们的
entry:编译入口,我们编译哪个文件
output:输出出口,注意这里并不能是字符串,这里是一个json里面path值得是输出的文件夹,filename值得是输出的文件名

打包多页面

git :day2
src下面创建new.js文件

alert("new")

创建index.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="dist/main.js"></script>
    <script src="dist/new.js"></script>
</head>
<body>
    
</body>
</html>

然后修改webpack.config.js配置,修改entry成为json对象,里面放置我们需要打包的文件路径,output的filename设置成通配符的方式,方便我们输出到dist目录下面

const path = require('path');
module.exports = {
    mode: "development",//调试模式
    entry: {
        new:'./src/new',
        index:'./src/index.js',
    },
    output: {
        path: path.resolve(__dirname, 'dist') ,//解析地址
        filename:'[name].js'
    }
}

然后终端执行webpack就会发现dist目录下面打包了两个文件,一切都掌握在我们手中,piu piu piu...

loader---解析为js认识的字符串

解析css

git: test3
load出场是必然的,因为webpack只能处理js和json数据,对于css 图片 视频 等等webpack不能编译,这里就需要左膀右臂loader出现了,注意loader的识别顺序是从后往前
例子:查看webpack如何通过loader解析识别css
这里我们需要安装style-loader(把样式输出到style标签) css-loader(读取并解析压缩css为js字符串)

cnpm i style-loader css-loader -D

在src文件夹下面创建css文件夹然后创建index.css文件

.box{
    width: 200px;
    height: 200px;
    background-color: aquamarine;
}

在src文件夹下面创建js文件夹然后创建index.js文件

import '../css/index.css';
alert("aaa")

创建index.html(这里我们不引用index.css文件因为很多css文件的话打包项目很大,这里我们使用webpack使用打包的文件)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="dist/bundle.js"></script>
</head> 

<body>
    <div class="box">

    </div>
</body>

</html>

webpack.config.js配置

const path = require('path');
module.exports = {
    mode: "development",//调试模式
    entry: './src/js/index.js',
    output: {
        path: path.resolve(__dirname, 'dist') ,//解析地址
        filename:'bundle.js'
    }
}

然后运行webpack出现如下结果:

image.png

不难发现webpack无法解析,此刻内心又是一万只xxx飘过。我们不会这么容易就束手就擒的,我们借助刚刚安装的css-loader和style-loader试试,修改webpack.config.js文件试试
增加module,rules规则是测试到.css结尾的文件使用style-loader','css-loader

const path = require('path');
module.exports = {
    mode: "development",//调试模式
    entry: './src/js/index.js',
    output: {
        path: path.resolve(__dirname, 'dist') ,//解析地址
        filename:'bundle.js'
    },
    module:{
        rules:[
            {test:/\.css$/i,use:['style-loader','css-loader']}
        ]
    }
}

然后我们webpack发现神奇的一幕发生了,界面回到了我们预想的结果。
我们打开我们的bundule.js文件发现css被转化为js字符串了

image.png

打开控制台发现style-loader把css文件添加到html里面去了
image.png

至此webpack如何通过loader解析并加载css文件到此结束

增加浏览器前缀

#div1 {
 -webkit-transform: rotate(40deg);
 -moz-transform: rotate(40deg);
 -ms-transform: rotate(40deg);
 -o-transform: rotate(40deg);
 transform: rotate(40deg);
}

对于上面的css代码我们需要手动加前缀,这样维护性太差,so我们的主角 postcss-loader出场了
国际管理
我们首先安装需要的load

cnpm i  postcss-loader autoprefixer -D

基于解析css的例子我们修改下index.css文件

.box{
    width: 200px;
    height: 200px;
    background-color: aquamarine;
    transform: rotate(0deg);
    transition:1s all ease;
  }
  
  .box:hover {
    transform: rotate(90deg);
  }

创建postcss.config.js文件

const autoprefixer = require("autoprefixer");
module.exports = {
    plugins: [
        autoprefixer 
    ]
}

修改webpack.config.js文件

const path = require('path');
module.exports = {
    mode: "development",//调试模式
    entry: './src/js/index.js',
    output: {
        path: path.resolve(__dirname, 'dist') ,//解析地址
        filename:'bundle.js'
    },
    module:{
        rules:[
            {test:/\.css$/i,use:['style-loader','css-loader','postcss-loader']}
        ]
    }
}

然后终端执行webpack,运行结果和我们心目中的想法是一样的,开心到原地爆炸

image.png

注意这里我们可以优化下webpack.config.js文件,把配置文件放在webpack.config.js更好管理

const path = require('path');
module.exports = {
    mode: "development",//调试模式
    entry: './src/js/index.js',
    output: {
        path: path.resolve(__dirname, 'dist') ,//解析地址
        filename:'bundle.js'
    },
    module:{
        rules:[
            {
                test: /\.css$/i, use: ['style-loader', 'css-loader',
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: [
                                require('autoprefixer')
                            ]
                        }
                    }
                    
                ]
            }
        ]
    }
}

接下来终端运行npx autoprefixer --info,查看下autoprefixer信息

image.png

然后我们就可以在package.json增加配置,支持浏览器最后的五个版本
image.png

打开终端如下:
image.png

处理图片文件

话不多说直接开干。基于cssloader项目我们修改下index.css文件,记得创建img文件夹并放进一站图片呦!!!

.box{
    width: 200px;
    height: 200px;
    background: url('../img/3.jpg') no-repeat ;
}

然后执行webpack

image.png

我凑!!!报错了,刚才引入的图片呢。被吃了吗?开动脑机器发现我没引入loader,于是我们清楚我们的主角
file-loader url-loader

npm i file-loader url-loader -D

修改webpack.config.js

const path = require('path');
module.exports = {
    mode: "development",//调试模式
    entry: './src/js/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),//解析地址
        filename: 'bundle.js'
    },
    module: {
        rules: [
            { test: /\.css$/i, use: ['style-loader', 'css-loader'] },
            {
                test: /\.(jpg|png|gif)$/i, use: {
                    loader: 'file-loader',
                    options: {
                        outputPath: 'img/',      //输出在哪个目录下面
                        publicPath: 'dist/img/', //输出真正引用的目录
                      }
                }
            }
        ]
    }
}

然后运行webpack,如你所料正常显示
这里简单啰嗦下file-loader和url-loader的区别,file-loader加载大文件,url-loader通过limit参数加载小文件,首先转换为base64的方式加载

处理less

国际惯例安装loader

cnpm i less-loader less -D

src下创建less文件夹并创建test.less文件

@bg_color:#CCC;

body {background:@bg_color;}

src下创建js文件夹并创建index.less文件

import '../less/test.less';

设置webpack.config.js配置

const path = require('path');
module.exports = {
    mode: "development",//调试模式
    entry: './src/js/index.js',
    output: {
        path: path.resolve(__dirname, 'dist') ,//解析地址
        filename:'bundle.js'
    },
    module:{
        rules:[
            {test: /\.less$/i, use: ['style-loader', 'css-loader', 'less-loader']}
        ]
    }
}

终端执行webpack,一切总是那么完美,xixi

处理es6

安装loader,注意这里还需要配置一个

cnpm i @babel/core babel-loader @babel/preset-env -D

src下面创建js并创建index.js

import '../less/test.less';
let a=12;
let b=5;

let sum=(n1, n2)=>n1+n2;

alert(sum(a, b));

创建index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="dist/bundle.js"></script>
</head> 

<body>
    <div class="box">

    </div>
</body>

</html>

配置webpack.config.js

const path = require('path');
module.exports = {
    mode: "development",//调试模式
    entry: './src/js/index.js',
    output: {
        path: path.resolve(__dirname, 'dist') ,//解析地址
        filename:'bundle.js'
    },
    module:{
        rules:[
            { test: /\.less$/i, use: ['style-loader', 'css-loader', 'less-loader'] },
            {test: /\.(js|jsx)$/i, use: {
                loader: 'babel-loader',
                options: {
                  presets: ['@babel/preset-env']
                }
              }}
        ]
    },
    devtool: 'source-map'
}

运行webpack,一切变得都是那么美好...