看完你就会用 webpack 了

终极目标

可使用 webpack 打包 vue 项目。css

整体计划

  1. webpack 安装和简单使用
  2. 经过配置文件增长打包的功能
  3. 学习各类loader可让webpack去打包各类文件
  4. 学习 plugins强大webpack 的功能
  5. 学会配置 webpack-dev-server 能够在开发过程当中实时更新预览代码
  6. 配置webpack 实现 .vue 文件的打包

webpack-安装基本使用

学习目标

  • 明白 webpack 的做用。
  • 掌握 webpack 的基本使用。
  • 解决项目中代码打包的问题。(经过 webpack 对代码进行打包)

学习计划

  1. webpack的用处。
  2. webpack 的安装环境
  3. webpack 的安装
  4. 代码文件结构
  5. 如何改造普通代码文件为模块化,便于 webpack 打包
  6. 使用 简单命令预览 webpack 打包效果
  7. 查看打包后的 js 并简单介绍下 webpack 打包依据。
  8. 经过 es6 模块化文件使用 webpack 打包
  9. 总结

开始学习

webpack 的世界 一切皆模块html

1. webpack 的做用(打包)

webpack 把模块收集梳理打包前端

  • 对咱们开发的项目进行打包(编译,把咱们的代码转换成浏览器能够编译的代码,例如 es6 转 es5,scss 转 css ,css 增长前缀,把.vue 拆分红.js和.css)
    • 开发过程当中时时编译
      • 经过 webpack server 生成一个临时的本地服务,对咱们开发的项目的代码进行时时编译。
    • 项目开发完毕对资源进行打包
      • 压缩
      • 不压缩

2. 安装 webpack

webpack中文网vue

1. 安装环境

  1. 安装 node,目前安装 node 会自动安装 npm。node

    node 中文网webpack

  2. 建立一个文件夹。例如 demo1es6

  3. 使用 npm 命令初始化 node 环境。web

    npm init -y
    复制代码

    这样会产生一个 package.json 文件正则表达式

    {
      "name": "demo1",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
    }
    
    复制代码

2. 安装webpack

1.在命令行工具中输入(推荐局部安装)vue-cli

npm i webpack webpack-cli -D
复制代码

当看到命令行中出现以下代码,表明安装成功了。

+ webpack-cli@3.3.12
+ webpack@4.43.0
added 391 packages from 218 contributors in 56.033s
复制代码
"devDependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.12"
  }
复制代码

i 是 install 的简写

-D 是--save-dev的简写,其包名称及版本号会存在 package.json 的 devDependencies 这个里面,而--save则会将包名称及版本号放在 dependencies 里面。

延伸:dependencies是运行时依赖,devDependencies是开发时的依赖 (这里你们知道就能够了,之后的课程会终点介绍)

webpack 4x以上,webpack将命令相关的内容都放到了webpack-cli,因此还须要安装webpack-cli。

注意:

  1. webpack 和 webpack-cli 推荐同时安装,这样能够保证webpack-cli 对应 当前安装的 webpack。

  2. 项目名称不要叫 webpack 会致使安装失败。

  3. 如何查看版本号?因为webpack 不是全局安装 查看版本不能使用

    webpack -v
    复制代码

    而是使用

    node_modules\.bin\webpack -v
    // 4.43.0
    复制代码

    或者

    npx webpack -v
    // 4.43.0
    复制代码

者来检测版本,注意这里npm版本号要求 5.2 以后。

npx webpack 等价于 node_modules\.bin\webpack

3. 建立基本文件代码

环境准备完成以后咱们开始建立几个基本文件,其目录结构以下:

deomo1/root
|-index.html
|-index.js
|-package.json
|-tool.js
复制代码

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>
</head>
<body>
    <div id="app"></div>
</body>
<script src="tool.js"></script>
<script src="./index.js"></script>
</html>
复制代码

tool.js 代码

const updateDom = (id, content) =>{
    window.document.getElementById(id).innerHTML =  content
}
复制代码

index.js 代码

updateDom('app','传智播客')
复制代码
痛点
  1. index.js 依赖 tool.js 因此 index.html 中文件不能够换位置

  2. 多人开发项目时候没法保证变量是否惟一性(变量冲突)。例如两个文件中分别存在 tool.js var a = 100;index.js var a =1000;

  3. 低版本浏览器不识别 ES6 语法。

  4. 代码没有通过混淆存在安全隐患,例如别人能够经过你的代码推断出服务器接口请求的一些参数。

  5. 随着 js 文件个数增长,增长了项目管理的难度,例如各个js 文件依赖,变量等等

解决方案

​ 经过使用 webpback 把多个 js 文件打包成一个。

4. 修改基本文件代码为模块化写法

本代码实例为 CommonJS 模块化写法,具体改造以下

tool.js

const updateDom = (id, content) =>{
    window.document.getElementById(id).innerHTML =  content
}
// nodejs中的模块
module.exports = {
    updateDom
}
复制代码

index.js

const {updateDom} = require('./tool');
updateDom('app','传智播客')
复制代码

改完以后的代码咱们再次直接经过浏览器打开发现浏览器报错,由于浏览器不能识别。接下来经过 webpack 对咱们的diamond进行打包操做。

注意

在 webpack 4 中,能够无须任何配置就可使用。

  1. 简单的打包操做

    npx webpack index.js //入口文件
    复制代码

    npx 解释见上文

    结果

    Hash: c4b4044439973defe187 Version: webpack 4.43.0 Time: 425ms Built at: 2020-07-16 4:51:35 PM Asset Size Chunks Chunk Names main.js 1.05 KiB 0 [emitted] main Entrypoint main = main.js [0] ./index.js 71 bytes {0} [built] [1] ./tool.js 160 bytes {0} [built] 复制代码

    同时根目录生成了一个叫作 dist 的文件夹里面存在一个 main.js 的文件。

    同时有一段黄色的警告,由于咱们没有告诉 webpack 咱们的须要打包的模式是开发模式(我理解为开发代码阶段)仍是生产模式(我通常理解为打包上线)。

5 打包后的 js

main.js 就是 index.jstool.js 两个文件打包后的结果。

基本原理 webpack 会分析入口文件中的引用关系把相关的文件合并到一块儿,例如:

若是 index.js 中没有引用 tool.js 那么打包的 main.js 就没有tool.js 的代码。

(简单给学生看下mian.js)

6. 引入打包后的js

修改 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>
</head>
<body>
    <div id="app"></div>
</body>
    <script src="./dist/main.js"></script>
</html>

复制代码

7. 使用 ES6 的模块化导出

建立一个 tooles6.js 文件

const log = (content) => {
    console.log(Date.now(), content)
}

// es6 模块化导出
export { log }

复制代码

在 index.js 文件中引入

// node 模块化导入
const {updateDom} = require('./tool');

 // es6 模块化导入
import {log} from './tooles6';

updateDom('app','传智播客')

log('测试webpack是否能识别es6的模块化')

复制代码

小结

  1. webpack 自动识别各类依赖处理打包文件
  2. webpack 经过入口文件
  3. webpack 能够用来打包多个或一个 js 文件(多个合成一个)
    1. 优势:没必要去关心它们的依赖
  4. 基于 node.js 不建议全局安装,直接经过 -D 安装到项目便可。
  5. 每次打包都会生成新的文件,若是有一样名字的会覆盖
  6. 支持两种模块化
    1. commonjs
    2. es6

webpack-基本配置

学习目标

咱们如何配置webpack 来知足咱们的需求?

咱们如何简化 webpack 的命令,能够快速使用

咱们如何自定义打包入口和出口路径?

经过下面的课程咱们能够掌握webpack 的基本配置知足咱们项目打包的基本需求。

学习计划

  1. 建立默认配置文件 webpack.config.js
  2. 指定配置文件进行打包操做
  3. 经过package.json 进行简化 webpack 的命令
  4. 自定义打包文件和输出文件位置及名称
  5. 总结

开始学习

在 webpack 4 中,能够无须任何配置使用,然而大多数项目会须要很复杂的设置,这就是为何 webpack 仍然要支持 配置文件。这比在终端(terminal)中手动输入大量命令要高效的多,因此让咱们建立一个配置文件,取代咱们以前使用 cli 命令执行的方式。

来自官网的一段话

webpack 在工做时,它会默认去根目录下找一个名为 webpback.config.js 的文件(若是找不到,则它会用一些默认设置)。

webpback.config.js 就是webpack的配置文件,在这个配置文件中,咱们能够经过一个 导出一个 json对象去配置webpback的参数,让打包更加灵活。

1. 建立默认配置文件 webpack.config.js

位置

咱们先指定一下打包模式 mode

module.exports = {
    mode: "development" // production(生产)
}
复制代码

接下来再次运行打包命令,查看产生的main.js文件的内容,对比与之间的变化。

  1. 黄色警告没有了,由于咱们已经设置了 mode。
  2. 咱们能够把 webpack 的配置文件想象成 webpack 是一个函数,它接受一个对象,经过对象来让 webapck 函数来产生咱们想要的结果。

此文件的意义是导出一个配置项:用来配置 webpack 如何打包。

在操做层面,就是学习如何去使用这个文件。

mode模式:

  • development:开发模式(代码不会压缩 混淆)
  • production:生产模式(压缩,混淆,加密....... 不可读)

2. 指定配置文件(自定义配置文件名)

目的

为了实现多种打包模式,例如开发模式,生产模式,咱们能够写在一个配置文件中可是它不利于维护。

我推荐把不一样功能的配置文件单独分开写,一般工做中也是这样的。

在默认状况下,webpack会找一个名为 webpack.config.js的文件做为它的配置文件,可是,针对不一样的场景,咱们能够自行决采用哪一个配置文件,换句话说,配置文件不必定必须叫webpack.config.js

下面,自已建立一个webpack.dev.js的文件用它来作配置文件,并使用它进行打包

1. 在根目录下建立自定义配置文件

在项目根目录下建立webpack.dev.js,内容以下:

module.exports = {
  mode: 'development',
  output:{
    filename:'bundle.js'
  }
}
复制代码

2. 使用这个文件进行打包的配置

基本格式
npx webpack --config webpack的配置文件 入口文件
复制代码
运行命令
npx webpack --config webpack.dev.js index.js
复制代码

3. 经过 package.json 中的 scripts 简化运行命令

基本格式
"scripts": {
    "自定义命令名": "要具体执行的代码",
  }
复制代码
示例
"scripts": {   
    "build": "webpack --config webpack.dev.js index.js"
 }
复制代码
运行命令
npm run build 
//至关因而 npx webpack --config webpack.dev.js  index.js
复制代码

4. 设置打包入口文件和出口路径

在webpack中:

  • 默认入口是:./src/index.js
  • 默认出口是:./dist/main.js。

1. 设置入口路径

咱们在实际工做中入口文件每每不是 index.js 也许叫 app.js

调整目录结构

|-package.json
|-index.html
|-src/
|-src/js
|-------app.js
|-------tool.js
|-------tooles6.js
复制代码
  • 修改src/index.js的名字为src/js/app.js

  • 在webpack.config.js的配置项中添加 entry ,以下

  • module.exports = {
      mode: 'development', // 打包方式
      entry:'./src/js/app.js' // 入口文件
    }
    复制代码
  • 修改快速打包命令

    • "scripts": {
         "build": "webpack"
       }
      复制代码
    • 由于咱们使用的是 webpack.config.js 全部这里不须要使用--config webpack.config.js 去指定配置文件。

  • 从新打包测试

npm run build
复制代码

2. 设置出口路径

  • 在webpack.config.js的配置项中添加 output ,以下

    • // 引入nodejs中的核心模块
      const path = require('path') 
      console.log(path.join(__dirname,'/build'))
      module.exports = {
          mode: "production",
          entry: './src/js/app.js', // 入口文件
          output: {
              "path": path.join(__dirname,'/build'), // 决定出口文件在哪里
              "filename": "bundle.js" // 设置出口文件的名字。默认状况下,它叫main.js
          }
      }
      复制代码
    • 说明:

      • output中的filename用来指定打包后的文件名字。
      • output中的path用来指定打包后的路径。注意:它必须是绝对路径。因此,这里引用path模块中的resolve方法来生成绝对路径。
      • 若是path中的路径不存在,它会自动建立一个默认的路径名称 dist
  • 从新打包测试

npm run build
复制代码

小结

  • webpack的配置文件默认名是webpack.config.js
  • 也能够单独指定 webpack 的配置文件来知足多种场景的须要。
  • 学习webpack就学习webpack.config.js的使用。
  • 把webpack的打包命令集成到script中能够简化打包命令,同时方便其余合做人员的使用。
  • 自行定义入口和出口文件

灵魂三问

​ 有什么用?

​ 打包

​ 为何用它?

​ 工程化:前端任务重须要有工具来管理

​ 开发、上线

​ 怎么用?

​ 学习 webpack.config.js 不用记住,多看文档,仅仅须要记住最外面基本配置做用便可。

webpack-高级配置

1. loader

介绍

为何用 loader?

webpack 在不使用loader的时候仅仅能够处理 .js 格式的文件,而咱们项目中有着各类格式的文件,以及须要对 js文件进行进一步处理例如 es6 转 es5。

1.目的

经过loader 对要打包的文件进行语法转化。

2.做用

将一个个文件以字符串的形式读入,对其进行语法分析及进行转换。

3.原理

能够把 loader 理解成一个翻译员,把源文件通过转换后输出结果,而且一个文件还能够链式的屡次翻译。

loader 也是一个模块,默认导出为一个 node 形式的函数,这个函数在 loader 进行资源转换时候调用,并经过 this上下文访问。

module.exports = function(source) {
  // source 为 compiler 传递给 Loader 的一个文件的原内容
  // 该函数须要返回处理后的内容,这里简单起见,直接把原内容返回了,至关于该`Loader`没有作任何转换
  return source;
};
复制代码

转换:一个Loader的职责是单一的,只须要完成一种转换。 若是一个源文件须要经历多步转换才能正常使用,就经过多个Loader去转换。 在调用多个Loader去转换一个文件时,每一个Loader会链式的顺序执行, 第一个Loader将会拿到需处理的原内容,上一个Loader处理后的结果会传给下一个接着处理,最后的Loader将处理后的最终结果返回给Webpack。 因此,在你开发一个Loader时,请保持其职责的单一性,你只需关心输入和输出。

实例

1. 使用 css-loader ,style-loader 处理文件中的 .css 文件

准备

public.css

body,html{
    padding:0;
    font-size:14px;
}
复制代码

style.css

@import "public.css";
div {
  border:4px solid #ccc;
  width: 50%;
  height: 200px;
  margin:30px auto;
  box-shadow: 3px 3px 3px #ccc;
  background-color: #fff;
  text-align: center; 
}
复制代码

app.js 增长引入 css 文件

// node 模块化导入
const {updateDom} = require('./tool');
 // es6 模块化导入
import {log} from './tooles6';
// + 新增 css 文件引入
import './../css/style';

updateDom('app','传智播客')

log('测试webpack是否能识别es6的模块化')
复制代码

使用 webpack 打包

npm run bulid
复制代码

此时控制台

咱们看到控制台报错,这里咱们只须要注意 关键子 loader 以及文件格式.css ,由此能够推断出是缺乏 css-loader

css-loader 安装

npm install css-loader -D
复制代码

-D devDependencies是开发时的依赖

css-loader 在webpack中配置

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['css-loader']
            },
        ],
    }
}
复制代码

在 expors 的对象内部增长 module 对象 经过配置 rules 数组进行 loader 的配置

执行顺序 :从数组的最末端开始执行,也能够简单的理解为从右往左。

执行命令及结果

此时打开浏览器观看 样式并无生效 css-loader 的做用就是帮助 webpack 读取 .css 文件,并打包进 bundle.js中,此时还须要 style-loader

安装

npm i style-loader -D
复制代码

使用

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            },
        ],
    }
}
复制代码

完整代码:

const path = require('path') 
console.log(path.join(__dirname,'/build'))
module.exports = {
    mode: "production",
    entry: './src/js/app.js', // 入口文件
    output: {
        "path": path.join(__dirname,'/build'), // 决定出口文件在哪里
        "filename": "bundle.js" // 设置出口文件的名字。默认状况下,它叫main.js
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            },
        ],
    }
}
复制代码

咱们看下输出的 .js 包

bundle.js中有一些js代码,它在运行时,会自动在.html文件中追加style标签,并输出样式。

扩展

eval("var api = __webpack_require__(/*! ../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js")
复制代码

再去node_modules\style-loader\dist\runtime\injectStylesIntoStyleTag.js 找下insertStyleElement这个方法,你就能够发现这个过程。

function insertStyleElement(options) {
  var style = document.createElement('style');
  var attributes = options.attributes || {};

  if (typeof attributes.nonce === 'undefined') {
    var nonce = typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null;

    if (nonce) {
      attributes.nonce = nonce;
    }
  }

  Object.keys(attributes).forEach(function (key) {
    style.setAttribute(key, attributes[key]);
  });

  if (typeof options.insert === 'function') {
    options.insert(style);
  } else {
    var target = getTarget(options.insert || 'head');

    if (!target) {
      throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
    }

    target.appendChild(style);
  }

  return style;
}
复制代码

此时浏览器就能够渲染样式了。

这里你们要注意 loader 的配置顺序。


小节 css-loader 帮助webpack 把.css 打包进去 style-loader 把打包的 .css 进行转换经过函数以 style标签的形式插入到 html 中。

扩展小知识** @import 用来引入另外一个 css 文件。

语法

@import url;
@import url list-of-media-queries;
@import [ <string> | <url> ] [ <media-query-list> ]?;
复制代码

解释

  • url:是一个表示要引入资源位置的 ](https://developer.mozilla.org/zh-CN/docs/Web/CSS/string) 或者 [ 。 这个 URL 能够是绝对路径或者相对路径。 要注意的是这个 URL 不须要指明一个文件; 能够只指明包名。
  • list-of-media-queries 是一个逗号分隔的 媒体查询 条件列表,决定经过URL引入的 CSS 规则 在什么条件下应用。若是浏览器不支持列表中的任何一条媒体查询条件,就不会引入URL指明的CSS文件。

实例

  • css文件中用法
/* 方法一*/
@import 'test.css';
/* 方法二*/
@import url(test.css);
/* @import url list-of-media-queries;*/
@import "common.css" screen, projection;
@import url('landscape.css') screen and (orientation:landscape);
复制代码
  • js 文件中用法
import 'test.css';
复制代码
2. 使用 less-loader 处理 .less 文件

安装

npm i less-loader  -D
// 不用在安装 less
npm i less-loader less  -D
复制代码

less-loader: 加载 less 文件而且把 .less 语法的代码转换成 .css

配置

module.exports = {
    module: {
        rules: [
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            }
        ],
    }
}
复制代码

完整代码

const path = require('path') 
console.log(path.join(__dirname,'/build'))
module.exports = {
    mode: "development", // development production
    entry: './src/js/app.js', // 入口文件
    output: {
        "path": path.join(__dirname,'/build'), // 决定出口文件在哪里
        "filename": "bundle.js" // 设置出口文件的名字。默认状况下,它叫main.js
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            }
        ],
    }
}
复制代码

这里你们要注意下 less 文件的 loader顺序

use:['style-loader','css-loader','less-loader']
复制代码

原理:先执行 less-loader 加载 .less 并转换成 css 把转换的结果给 css-loader ,css-loader 把结果在处理给 style-loader , 若是只配置 less-loader webpback 没法识别 css 格式。由于每一个 test 都是一个处理模块 webpack 不会把 test:/.css/ 的规则用来处理 /.less/

代码改造

index.less

@import "style.css";

body{ 
  div {
    border:4px solid #ccc;
    width: 50%;
    height: 200px;
    margin:30px auto;
    box-shadow: 3px 3px 3px #ccc;
    background-color: #fff;
    text-align: center; 
  }
}
复制代码

app.js

// node 模块化导入
const {updateDom} = require('./tool');
// 引入 less 文件
import '../css/index.less'
// 引入 css 文件
// import './../css/style.css';
 // es6 模块化导入
import {log} from './tooles6';

updateDom('app','传智播客')

log('测试webpack是否能识别es6的模块化')
复制代码

执行打包命令而且在浏览器中查看

3. 使用 url-loader file-loader 处理图片资源

前端开发不可避免的使用各类图片资源

代码改造

index.less 文件

@import "style.css";

body{ 
  div {
    border:4px solid #ccc;
    width: 50%;
    height: 200px;
    margin:30px auto;
    box-shadow: 3px 3px 3px #ccc;
    background-color: #fff;
    text-align: center; 
    background-image: url(./../img/webpack-png.png);
  }
}
复制代码

安装 url-loader

npm i url-loader - D
复制代码

配置

module.exports = {
    module: {
        rules: [
             {
                test:/\.png/,
                use:['url-loader']
            }
        ],
    }
}
复制代码

执行

npm run build
复制代码

结果

咱们发现只有一个js文件,那是由于 url-loader 把图片文件转换成了 base 64。

优势:减小网络请求。

缺点: 增长了 js包大小。

base64 通常比图片会大一点点。

如何选择?

小文件能够转换成 base 64,大文件不推荐。

url-loader 高级配置

咱们使用loader 的时候,以前是 use:['xxx-loader'],若是想详细的设置loader能够以下

通用规则

use:[
    {
        loader:'xxx-loader',
        options:{

        }}
]
复制代码

若是你不是很了解能够经过 npm 去找对应的loader,例如

配置完成后的代码

const path = require('path') 
console.log(path.join(__dirname,'/build'))
module.exports = {
    mode: "development", // development production
    entry: './src/js/app.js', // 入口文件
    output: {
        "path": path.join(__dirname,'/build'), // 决定出口文件在哪里
        "filename": "bundle.js" // 设置出口文件的名字。默认状况下,它叫main.js
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            {
                test:/\.png/,
                use:[{
                    loader:'url-loader',
                    options:{
                        limit:3*1024 // 3* 1024b = 3kb
                    }
                }]
            }
        ],
    }
}
复制代码

执行 build结果以下:

这是由于咱们经过配置 url-loder 使得它只处理 3k 一下的图片,并转换成 base64,若是须要处理大于 3kb的须要使用 file-loader 。

安装 file-loader

npm i file-loader -D
复制代码

执行代码结果

这个时候咱们发现并无 配置 file-loader 就能够直接起做用了。

注意

浏览器查看

此时页面上面并不会显示图片,由于 file-loader 仅仅把图片复制过去。这时候咱们查看路径,浏览器中是找不到路径的。这时候右键查看图片路径,咱们能够很清楚的看到咱们的图片路径位置是不对的

缘由

上述代码设置了 limit 选项,意思是当图片体积小于 8192 字节时,会转换成 base 编码字符串,当图片体积大于 8192 字节时,默认会使用 file-loader。

解决方案 (若是你们看着笔记去学习,这里建议了解下直接跳过,由于后面经过 webpack 新增的 plugin 配置就会解决这个问题,不要浪费时间在这里)

修改 css 引用路径为file-loader处理图片后的路径。

  1. 工具 mini-css-extract-plugin 参考下面的内容配置

可是 mini-css-extract-plugin 一般是项目打包的时候才会用到。

扩展配置

咱们的 url-loader 功能强大,它能够处理多种格式的文件,那么怎么优化配置 呢?具体以下

{
    test:/(\.png|\.jpg|\.svg)/,
    use:[{
        loader:'url-loader',
        options:{
        limit:3*1024 // 3* 1024b = 3kb
        }
    }]
}
复制代码

其实就是使用正则表达式把咱们想用 url-loader 处理的文件写在 test里面这样就能够匹配啦。

优化配置 经过配置 name 能够修改 打包以后图片的名称和输出位置

{
    test:/\.png/,
        use:[{
            loader:'url-loader',
            options:{
                limit:3*1024, // 3* 1024b = 3kb
                name:'img/[name].[ext]'
            }
        }]
}
复制代码

因为咱们的 output 路径写的式 build 因此这里的name 能够成上面的样子,name 是原来文件名称 ext是文件类型

测试svg文件

代码改造

index.less

@import "style.css";
body{ 
  background: url(./../img/webpack-svg.svg);
  div {
    border:4px solid #ccc;
    width: 50%;
    height: 200px;
    margin:30px auto;
    box-shadow: 3px 3px 3px #ccc;
    background-color: #fff;
    text-align: center; 
    background-image: url(./../img/webpack-png.png);
  }  
}
复制代码

执行打包

由于咱们的svg图片小于 3k 因此 url-loader 把svg资源转成了 base64 大到了js里面

loader 小结

如何使用

  1. 根据文件类型下载对应的loader。
  2. 配置loader。

2. plugin 插件

介绍

1. 目的

插件在于解决 loader 没法实现的其余事

2. 做用

plugin是用于扩展webpack的功能,

3. 经常使用 plugin 总结

html-webpack-plugin

功能:把咱们自已写的.html文件复制到指定打包出口目录下,并引入相关的资源代码。

mini-css-extract-plugin

功能:这个插件帮助咱们把css代码提取到一个独立的文件中(而不是以style的方式嵌在html文件中)。

clean-webpack-plugin

在生成打包文件以前,把目录清空掉。

实例

1. mini-css-extract-plugin

安装过程

  1. 下载插件
npm i mini-css-extract-plugin -D
复制代码
  1. 在配置文件中引入

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
复制代码
  1. 修改 webpack.config.js 的 module.exports 中的 rules

    module.exports = {
        module:{
            rules:[
                 {
                     // 替换 style-loadr 为 {loader: MiniCssExtractPlugin.loader}这个配置是咱们项目打包上线经常使用的写法。
                    test:/\.less$/,
                    use:[{loader: MiniCssExtractPlugin.loader},'css-loader','less-loader']
                },
            ]
        }
    }
    复制代码
  2. 在 webpack.config.js 的 module.exports 增长 plugins。全部的插件都须要在这里面new 一下

    plugins:[
            new MiniCssExtractPlugin({
                // [name], [hash] 是占位符
                // name: 表示入口文件的名称
                // hash: 一串随机值,是用于区别于本次打包与其它打包的过程。因为源文件有变化,则每次打包时hash都不一样
                filename: '[name]-[hash].css',
            })
        ]
    复制代码

    完整代码

    const path = require('path') 
    +const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    console.log(path.join(__dirname,'/build'))
    module.exports = {
        mode: "development", // development production
        entry: './src/js/app.js', // 入口文件
        output: {
            "path": path.join(__dirname,'/build'), // 决定出口文件在哪里
            "filename": "bundle.js", // 设置出口文件的名字。默认状况下,它叫main.js 
        },
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: ['style-loader','css-loader']
                },
                {
                    test:/\.less$/,
       +             use:[{loader: MiniCssExtractPlugin.loader},'css-loader','less-loader']
                },
                {
                    test:/(\.png|\.jpg|\.svg)/,
                    use:[{
                        loader:'url-loader',
                        options:{
                            limit:3*1024, // 3* 1024b = 3kb 
                        }
                    }]
                }
            ],
        },
    +    plugins:[
            new MiniCssExtractPlugin({
                // [name], [hash] 是占位符
                // name: 表示入口文件的名称
                // hash: 一串随机值,是用于区别于本次打包与其它打包的过程。因为源文件有变化,则每次打包时hash都不一样
                filename: '[name]-[hash].css',
            })
        ]
    }
    复制代码

执行打包命令

注意

这时后咱们的 index.html 路径是不对的

咱们的index.html 没有引用,这时候打开浏览器是看不到样式的,这时候我看额能够手动修改下 css 文件的引用地址。

2. html-webpack-plugin
  1. 安装
npm i html-webpack-plugin -D
复制代码
  1. 在配置文件中引入。

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
复制代码
  1. 在 webpack.config.js 的 plugins 中 new HtmlWebpackPlugin并配置
plugins: [
    new HtmlWebpackPlugin({ // 打包输出HTML
        minify: { // 压缩HTML文件
            removeComments: true, // 移除HTML中的注释
            collapseWhitespace: true, // 删除空白符与换行符
            minifyCSS: true// 压缩内联css
        },
        filename: 'index.html',
        template: path.resolve('./index.html') // 指定模块的位置
    })
]
复制代码

删除 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>
    <!-- <link rel="stylesheet" href="./src/css/style.css"> -->
</head>
<body>
    <div id="app"></div>
</body>
<!--
    不经过webpack打包
     <script src="tool.js"></script> 
    <script src="./index.js"></script>
-->
<!-- 使用webpack 打包生成的文件路径 -->
<!-- <script src="./build/bundle.js"></script> -->
</html>
复制代码

执行代码结果

build 里面多了一个 html。

删除HtmlWebpackPlugin 压缩的配置项

plugins: [
    new HtmlWebpackPlugin({ // 打包输出HTML 
        filename: 'index.html',
        template: path.resolve('./index.html') // 指定模块的位置
    })
]
复制代码

打包后的结果

咱们发现 url-loader 以前处理路径有问题的背景图片也显示出来了。

这些配置项咱们一样能够在 npm 包的网站中找到,不须要去记住。接下来咱们在添加一个插件去巩固下咱们的知识。

3. clean-webpack-plugin

下载插件

npm i clean-webpack-plugin -D
复制代码

配置文件webpack.config.js

const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
    plugins: [
    new CleanWebpackPlugin()
]	
}

复制代码

执行效果

所有代码

const path = require('path') 
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
console.log(path.join(__dirname,'/build'))
module.exports = {
    mode: "development", // development production
    entry: './src/js/app.js', // 入口文件
    output: {
        "path": path.join(__dirname,'/build'), // 决定出口文件在哪里
        "filename": "bundle.js", // 设置出口文件的名字。默认状况下,它叫main.js 
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:[{loader: MiniCssExtractPlugin.loader},'css-loader','less-loader']
            },
            {
                test:/(\.png|\.jpg|\.svg)/,
                use:[{
                    loader:'url-loader',
                    options:{
                        limit:3*1024, // 3* 1024b = 3kb 
                    }
                }]
            }
        ],
    },
    plugins:[
        new MiniCssExtractPlugin({
            // [name], [hash] 是占位符
            // name: 表示入口文件的名称
            // hash: 一串随机值,是用于区别于本次打包与其它打包的过程。因为源文件有变化,则每次打包时hash都不一样
            filename: '[name]-[hash].css',
        }),
        new HtmlWebpackPlugin({ // 打包输出HTML
            minify: { // 压缩HTML文件
                removeComments: true, // 移除HTML中的注释
                collapseWhitespace: true, // 删除空白符与换行符
                minifyCSS: true// 压缩内联css
            },
            filename: 'index.html',
            template: path.resolve('./index.html') // 指定模块的位置
        }),
        new CleanWebpackPlugin()
    ]
}
复制代码

plugin 使用小结

plugin 用来加强 webpack 的能力

有了上面三个插件的使用经验咱们总结下安装插件的步骤和注意点

  1. npm 包下载插件。
  2. 在配置文件中引入插件。
  3. 在 plugin的数组中 new 这个插件。

注意:

  1. 有些插件是直接导出的函数,而有些插件是导出的对象,例如const { CleanWebpackPlugin } = require('clean-webpack-plugin'),当咱们引用npm 包报错时候能够去 npm 包官网查看下使用 demo。
  2. 全部的插件都必定会在 plugins 数组里面经过 new 实例化。
  3. 插件在 plugins 中的顺序不是它调用的顺序,它的调用顺序和 webpack 执行过程有关系。

3. webpack-dev-server

目的: 在开发过程当中实时更新咱们的代码。

如何配置?

  1. 使用 npm 下载包

    npm i webpack-dev-server  -D
    复制代码
  2. 在配置文件最外层配置

    module.exports = {
        // 配置 webpack-dev-server的选项
        devServer: {
            host: '127.0.0.1',  // 配置启动ip地址
            port: 8081,  // 配置端口
            open: true  // 配置是否自动打开浏览器
        }
        // 其它配置
    }
    复制代码
  3. 修改 package.json 的快速启动配置

    "scripts": {
        "build": "webpack",
    +    "dev":"webpack-dev-server"
      },
    复制代码

    执行新配置的命令

    npm run dev
    复制代码

    这时咱们的浏览器就打开了,而且端口号是 8081,若是咱们不想让咱们的项目端口号和其余的项目冲突,能够去掉 port webpback 就会根据当前 系统端口占用状况自动生成一个端口号。

小结

webpack-dev-server 解决了咱们开发过程当中代码实时预览的问题,给咱们的开发代来了方便,它的功能不只仅如此,还可经过它配置跨越等功能。

3. webpoack 处理 .vue 文件

介绍

1 . 目的

经过webpack 能够处理打包 .vue 文件

配置

代码准备

vue 文件 /vuecomponents/App.vue

<template>
  <div>
    vue组件 {{title}}
  </div>
</template>

<script> export default { name: '', data() { return { title:'webpack-vue-这里的vue单文件组件' } } } </script>

复制代码

/js/main.js

import Vue from "vue"
import App from '../vuecomponents/app.vue'
new Vue({
  render(h) {
    return h(App)
  },
}).$mount("#app")
复制代码

咱们这里引用了 vue 全部要在 npm 中下载 vue

npm i vue -D
复制代码

分析

  1. 咱们新增 main.js 因此要修改配置文件 entry
  2. 咱们要让webpack 识别 .vue 因此要安装 vue-loader
  3. 须要解析 .vue 的模板因此要有 vue-template-compiler
  4. 须要处理 .vue 内部的 style 全部要有 vue-style-loader

安装依赖

npm i vue-loader  vue-template-compiler vue-style-loader -D
复制代码

修改配置 webpack.config.js

  1. 修改 entry

    entry: './src/js/main.js',
    复制代码
  2. 给.vue文件添加loader

  3. 添加VueLoaderPlugin

Vue-loader在15.*以后的版本都是 vue-loader的使用都是须要伴生 VueLoaderPlugin的。

vue-style-loader 和 以前的 file-loader相似不须要单独配置。

{
    // 若是是.vue文件,使用以下的loader
    test: /\.vue$/,
        loader: 'vue-loader'
}

复制代码
const VueLoaderPlugin = require('vue-loader/lib/plugin')

复制代码

上面这段代码是官网提供的配置实例

plugins:[
    new VueLoaderPlugin()
]

复制代码

完整代码

const path = require('path') 
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
    mode: "development", // development production
    entry: './src/js/main.js', // 入口文件
    
    output: {
        "path": path.join(__dirname,'/build'), // 决定出口文件在哪里
        "filename": "bundle.js", // 设置出口文件的名字。默认状况下,它叫main.js 
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:[{loader: MiniCssExtractPlugin.loader},'css-loader','less-loader']
            },
            {
                test:/(\.png|\.jpg|\.svg)/,
                use:[{
                    loader:'url-loader',
                    options:{
                        limit:3*1024, // 3* 1024b = 3kb 
                        name:'img/[name].[ext]'                   
                    }
                }]
            },
            {
                // 若是是.vue文件,使用以下的loader
                test: /\.vue$/,
                    loader: 'vue-loader'
            }
        ],
    },
    plugins:[
        new MiniCssExtractPlugin({
            // [name], [hash] 是占位符
            // name: 表示入口文件的名称
            // hash: 一串随机值,是用于区别于本次打包与其它打包的过程。因为源文件有变化,则每次打包时hash都不一样
            filename: '[name]-[hash].css',
        }),
        new HtmlWebpackPlugin({ // 打包输出HTML
            
            filename: 'index.html',
            template: path.resolve('./index.html') // 指定模块的位置
        }),
        new CleanWebpackPlugin(),
        new VueLoaderPlugin()
    ],
    devServer: {
        host: '127.0.0.1',  // 配置启动ip地址
        port: 8081,  // 配置端口
        open: true  // 配置是否自动打开浏览器
    }
}

复制代码

执行命令效果

小结

  1. 处理 .vue 咱们已经分析了 就是须要loader。
  2. 由此能够得出 webpack 的模块化其实并不复杂,咱们在使用它去为咱们的项目打包的时候经过要处理的文件类型,目的去 npm 包网站上或者 webpack网站中找到对应的依赖包就能够
  3. 咱们要掌握的是 webpack 的一般用法,和可以明白在打包过程当中为何会有错误,以及能够经过 webpack 提供的信息去配置。

总结

  1. webpack 是一个打包工具
  2. 在 webpack 的世界里一切皆模块。
  3. loader 帮助 webpack 去翻译不一样的文件让 webpack 能够把它们打包
  4. plugin 插件完善了 webpack 打包功能
  5. vue-cli 也是基于 webpack 开发实现的
相关文章
相关标签/搜索