小林

小林 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑

码农奋斗进行中

个人动态

小林 提出了问题 · 10月19日

vue如何实现web打印(标签、合同、单据)

之前公司通过调用FastReport插件实现打印功能,现在想要在web端实现类似功能,各位大佬请问有什么好的方案吗?

关注 2 回答 1

小林 提出了问题 · 10月18日

vscode 关于js文件内自定义组件格式化问题

这是没有格式化前
image.png
格式化后报错了
image.png
image.png
请问如何保持格式化前的格式?

关注 3 回答 2

小林 提出了问题 · 10月14日

nodejs Log4js 如何设置报错才生成日志?

image.png
项目运行时就创建日志,但是项目还没报错,如果做到报错才生成日志

关注 2 回答 1

小林 关注了标签 · 1月4日

关注 1929

小林 收藏了文章 · 1月4日

0202年了, Chrome DevTools 你还只会console.log吗 ?

chrome.png

前言

Chrome 开发者工具(简称 DevTools)是一套 Web 开发调试工具,内嵌于 Google Chrome 浏览器中。DevTools 使开发者更加深入的了解浏览器内部以及他们编写的应用。通过使用 DevTools,可以更加高效的定位页面布局问题,设置 JavaScript 断点并且更好的理解代码优化。

本文分享 24 个 Chrome 调试技巧和一些快捷键,希望能帮你进一步了解 Chrome DevTools ~

调试技巧

1. 控制台中直接访问页面元素

在元素面板选择一个元素,然后在控制台输入$0,就会在控制台中得到刚才选中的元素。如果页面中已经包含了 jQuery,你也可以使用$($0)来进行选择。

你也可以反过来,在控制台输出的 DOM 元素上右键选择 Reveal in Elements Panel 来直接在 DOM 树种查看。

0.gif

2. 访问最近的控制台结果

在控制台输入$_可以获控制台最近一次的输出结果。

_.gif

3. 访问最近选择的元素和对象

控制台会存储最近 5 个被选择的元素和对象。当你在元素面板选择一个元素或在分析器面板选择一个对象,记录都会存储在栈中。 可以使用$x来操作历史栈,x 是从 0 开始计数的,所以$0 表示最近选择的元素,$4 表示最后选择的元素。

4.png

4. 选择元素

  • $() - 返回满足指定 CSS 规则的第一个元素,此方法为 document.querySelector()的简化。
  • $$() - 返回满足指定 CSS 规则的所有元素,此方法为 querySelectorAll()的简化。
  • $x() - 返回满足指定 XPath 的所有元素。

select.png

5. 使用 console.table

该命令支持以表格的形式输出日志信息。打印复杂信息时尝试使用 console.table 来替代 console.log 会更加清晰。

table.png

6. 使用 console.dir,可简写为 dir

console.dir(object)/dir(object) 命令可以列出参数 object 的所有对象属性。

dir.gif

7. 复制 copy

你可以通过 copy 方法在控制台里复制你想要的东西。

copy.gif

8. 获取对象键值 keys(object)/values(object)

keys_values.png

9. 函数监听器 monitor(function)/unmonitor(function)

monitor(function),当调用指定的函数时,会将一条消息记录到控制台,该消息指示调用时传递给该函数的函数名和参数。

使用 unmonitor(函数)停止对指定函数的监视。

monitor.png

10. 事件监听器 monitorEvents(object[, events])/unmonitorEvents(object[, events])

monitorEvents(object[, events]),当指定的对象上发生指定的事件之一时,事件对象将被记录到控制台。事件类型可以指定为单个事件或事件数组。

unmonitorevent (object[, events])停止监视指定对象和事件的事件。

monitorevents.png

11. 耗时监控

通过调用 time()可以开启计时器。你必须传入一个字符串参数来唯一标记这个计时器的 ID。当你要结束计时的时候可以调用 timeEnd(),并且传入指定的名字。计时结束后控制台会打印计时器的名字和具体的时间。

time.png

12. 分析程序性能

在 DevTools 窗口控制台中,调用 console.profile()开启一个 JavaScript CPU 分析器.结束分析器直接调用 console.profileEnd().

profile.png

profile_1.png

13. 统计表达式执行次数

count()方法用于统计表达式被执行的次数,它接受一个字符串参数用于标记不同的记号。如果两次传入相同的字符串,该方法就会累积计数。

count.png

14. 清空控制台历史记录

可以通过下面的方式清空控制台历史:

  • 在控制台右键,或者按下 Ctrl 并单击鼠标,选择 Clear Console。
  • 在脚本窗口输入 clear()执行。
  • 在 JavaScript 脚本中调用 console.clear()。
  • 使用快捷键 Cmd + K (Mac) Ctrl + L (Windows and Linux)。

clear.gif

15. 异步操作

async/await 使得异步操作变得更加容易和可读。唯一的问题在于 await 需要在 async 函数中使用。Chrome DevTools 支持直接使用 await。

await.png

16. debugger 断点

有时候我们需要打断点进行单步调试,一般会选择在浏览器控制台直接打断点,但这样还需要先去 Sources 里面找到源码,然后再找到需要打断点的那行代码,比较麻烦。

使用 debugger 关键词,我们可以直接在源码中定义断点,方便很多。
debugger.png

17. 截图

我们经常需要截图,Chrome DevTools 提供了 4 种截图方式,基本覆盖了我们的需求场景,快捷键 ctrl+shift+p ,打开 Command Menu,输入 screenshot,可以看到以下 4 个选项:
screenshot.png

去试试吧,很香!

18. 切换主题

Chrome 提供了 亮&暗 两种主题,当你视觉疲劳的时候,可以 switch 哦, 快捷键 ctrl+shift+p ,打开 Command Menu,输入 theme ,即可选择切换

theme.gif

19. 复制 Fetch

在 Network 标签下的所有的请求,都可以复制为一个完整的 Fetch 请求的代码。

copy-fetch.gif

20. 重写 Overrides

在 Chrome DevTools 上调试 css 或 JavaScript 时,修改的属性值在重新刷新页面时,所有的修改都会被重置。

如果你想把修改的值保存下来,刷新页面的时候不会被重置,那就看看下面这个特性(Overrides)吧。Overrides 默认是关闭的,需要手动开启,开启的步骤如下。

开启的操作:

打开 Chrome DevTools 的 Sources 标签页
选择 Overrides 子标签
选择 + Select folder for overrides,来为 Overrides 设置一个保存重写属性的目录

overrides.png

21. 实时表达式 Live Expression

从 chrome70 起,我们可以在控制台上方可以放一个动态表达式,用于实时监控它的值。Live Expression 的执行频率是 250 毫秒。

点击 "Create Live Expression" 眼睛图标,打开动态表达式界面,输入要监控的表达式

live_expression.gif

22. 检查动画

Chrome DevTools 动画检查器有两个主要用途。

  • 检查动画。您希望慢速播放、重播或检查动画组的源代码。
  • 修改动画。您希望修改动画组的时间、延迟、持续时间或关键帧偏移。 当前不支持编辑贝塞尔曲线和关键帧。

动画检查器支持 CSS 动画、CSS 过渡和网络动画。当前不支持 requestAnimationFrame 动画。

快捷键 ctrl+shift+p ,打开 Command Menu,键入 Drawer: Show Animations。

animation

23. 滚动到视图区域 Scroll into view

scrollintoview.png

24. 工作区编辑文件 Edit Files With Workspaces

工作空间使您能够将在 Chrome Devtools 中进行的更改保存到计算机上相同文件的本地副本。

进入 Sources Menu, Filesystem 下 点击 Add folder to workspace 添加要同步的工作目录

workspace

快捷键

访问 DevTools

访问 DevToolsWindowsMac
打开 Developer Tools (上一次停靠菜单)F12、Ctrl + Shift + ICmd + Opt + I
打开/切换检查元素模式和浏览器窗口Ctrl + Shift + CCmd + Shift + C
打开 Developer Tools 并聚焦到控制台Ctrl + Shift + JCmd + Opt + J

全局键盘快捷键

下列键盘快捷键可以在所有 DevTools 面板中使用:

全局键盘快捷键WindowsMac
下一个面板Ctrl + ]Cmd + ]
上一个面板Ctrl + [Cmd + [
更改 DevTools 停靠位置Ctrl + Shift + DCmd + Shift + D
打开 Device ModeCtrl + Shift + MCmd + Shift + M
切换控制台EscEsc
刷新页面F5、Ctrl + RCmd + R
刷新忽略缓存内容的页面Ctrl + F5、Ctrl + Shift + RCmd + Shift + R
在当前文件或面板中搜索文本Ctrl + FCmd + F
在所有源中搜索文本Ctrl + Shift + FCmd + Opt + F
按文件名搜索(除了在 Timeline 上)Ctrl + O、Ctrl + PCmd + O、Cmd + P
放大(焦点在 DevTools 中时)Ctrl + +Cmd + Shift + +
缩小Ctrl + -Cmd + Shift + -
恢复默认文本大小Ctrl + 0Cmd + 0
打开 command 菜单Ctrl + Shift + PCmd + Shift + P

控制台

控制台快捷键WindowsMac
上一个命令/行向上键向上键
下一个命令/行向下键向下键
聚焦到控制台Ctrl + `Ctrl + `
清除控制台Ctrl + LCmd + K
多行输入Shift + EnterShift + Enter
执行EnterReturn

后记

如果你和我一样喜欢前端,也爱动手折腾,欢迎关注我一起玩耍啊~ ❤️

github 地址,欢迎 follow 哦~

博客

我的博客,点 star,不迷路~

公众号

前端时刻

qrcode.jpg

查看原文

小林 赞了文章 · 1月4日

0202年了, Chrome DevTools 你还只会console.log吗 ?

chrome.png

前言

Chrome 开发者工具(简称 DevTools)是一套 Web 开发调试工具,内嵌于 Google Chrome 浏览器中。DevTools 使开发者更加深入的了解浏览器内部以及他们编写的应用。通过使用 DevTools,可以更加高效的定位页面布局问题,设置 JavaScript 断点并且更好的理解代码优化。

本文分享 24 个 Chrome 调试技巧和一些快捷键,希望能帮你进一步了解 Chrome DevTools ~

调试技巧

1. 控制台中直接访问页面元素

在元素面板选择一个元素,然后在控制台输入$0,就会在控制台中得到刚才选中的元素。如果页面中已经包含了 jQuery,你也可以使用$($0)来进行选择。

你也可以反过来,在控制台输出的 DOM 元素上右键选择 Reveal in Elements Panel 来直接在 DOM 树种查看。

0.gif

2. 访问最近的控制台结果

在控制台输入$_可以获控制台最近一次的输出结果。

_.gif

3. 访问最近选择的元素和对象

控制台会存储最近 5 个被选择的元素和对象。当你在元素面板选择一个元素或在分析器面板选择一个对象,记录都会存储在栈中。 可以使用$x来操作历史栈,x 是从 0 开始计数的,所以$0 表示最近选择的元素,$4 表示最后选择的元素。

4.png

4. 选择元素

  • $() - 返回满足指定 CSS 规则的第一个元素,此方法为 document.querySelector()的简化。
  • $$() - 返回满足指定 CSS 规则的所有元素,此方法为 querySelectorAll()的简化。
  • $x() - 返回满足指定 XPath 的所有元素。

select.png

5. 使用 console.table

该命令支持以表格的形式输出日志信息。打印复杂信息时尝试使用 console.table 来替代 console.log 会更加清晰。

table.png

6. 使用 console.dir,可简写为 dir

console.dir(object)/dir(object) 命令可以列出参数 object 的所有对象属性。

dir.gif

7. 复制 copy

你可以通过 copy 方法在控制台里复制你想要的东西。

copy.gif

8. 获取对象键值 keys(object)/values(object)

keys_values.png

9. 函数监听器 monitor(function)/unmonitor(function)

monitor(function),当调用指定的函数时,会将一条消息记录到控制台,该消息指示调用时传递给该函数的函数名和参数。

使用 unmonitor(函数)停止对指定函数的监视。

monitor.png

10. 事件监听器 monitorEvents(object[, events])/unmonitorEvents(object[, events])

monitorEvents(object[, events]),当指定的对象上发生指定的事件之一时,事件对象将被记录到控制台。事件类型可以指定为单个事件或事件数组。

unmonitorevent (object[, events])停止监视指定对象和事件的事件。

monitorevents.png

11. 耗时监控

通过调用 time()可以开启计时器。你必须传入一个字符串参数来唯一标记这个计时器的 ID。当你要结束计时的时候可以调用 timeEnd(),并且传入指定的名字。计时结束后控制台会打印计时器的名字和具体的时间。

time.png

12. 分析程序性能

在 DevTools 窗口控制台中,调用 console.profile()开启一个 JavaScript CPU 分析器.结束分析器直接调用 console.profileEnd().

profile.png

profile_1.png

13. 统计表达式执行次数

count()方法用于统计表达式被执行的次数,它接受一个字符串参数用于标记不同的记号。如果两次传入相同的字符串,该方法就会累积计数。

count.png

14. 清空控制台历史记录

可以通过下面的方式清空控制台历史:

  • 在控制台右键,或者按下 Ctrl 并单击鼠标,选择 Clear Console。
  • 在脚本窗口输入 clear()执行。
  • 在 JavaScript 脚本中调用 console.clear()。
  • 使用快捷键 Cmd + K (Mac) Ctrl + L (Windows and Linux)。

clear.gif

15. 异步操作

async/await 使得异步操作变得更加容易和可读。唯一的问题在于 await 需要在 async 函数中使用。Chrome DevTools 支持直接使用 await。

await.png

16. debugger 断点

有时候我们需要打断点进行单步调试,一般会选择在浏览器控制台直接打断点,但这样还需要先去 Sources 里面找到源码,然后再找到需要打断点的那行代码,比较麻烦。

使用 debugger 关键词,我们可以直接在源码中定义断点,方便很多。
debugger.png

17. 截图

我们经常需要截图,Chrome DevTools 提供了 4 种截图方式,基本覆盖了我们的需求场景,快捷键 ctrl+shift+p ,打开 Command Menu,输入 screenshot,可以看到以下 4 个选项:
screenshot.png

去试试吧,很香!

18. 切换主题

Chrome 提供了 亮&暗 两种主题,当你视觉疲劳的时候,可以 switch 哦, 快捷键 ctrl+shift+p ,打开 Command Menu,输入 theme ,即可选择切换

theme.gif

19. 复制 Fetch

在 Network 标签下的所有的请求,都可以复制为一个完整的 Fetch 请求的代码。

copy-fetch.gif

20. 重写 Overrides

在 Chrome DevTools 上调试 css 或 JavaScript 时,修改的属性值在重新刷新页面时,所有的修改都会被重置。

如果你想把修改的值保存下来,刷新页面的时候不会被重置,那就看看下面这个特性(Overrides)吧。Overrides 默认是关闭的,需要手动开启,开启的步骤如下。

开启的操作:

打开 Chrome DevTools 的 Sources 标签页
选择 Overrides 子标签
选择 + Select folder for overrides,来为 Overrides 设置一个保存重写属性的目录

overrides.png

21. 实时表达式 Live Expression

从 chrome70 起,我们可以在控制台上方可以放一个动态表达式,用于实时监控它的值。Live Expression 的执行频率是 250 毫秒。

点击 "Create Live Expression" 眼睛图标,打开动态表达式界面,输入要监控的表达式

live_expression.gif

22. 检查动画

Chrome DevTools 动画检查器有两个主要用途。

  • 检查动画。您希望慢速播放、重播或检查动画组的源代码。
  • 修改动画。您希望修改动画组的时间、延迟、持续时间或关键帧偏移。 当前不支持编辑贝塞尔曲线和关键帧。

动画检查器支持 CSS 动画、CSS 过渡和网络动画。当前不支持 requestAnimationFrame 动画。

快捷键 ctrl+shift+p ,打开 Command Menu,键入 Drawer: Show Animations。

animation

23. 滚动到视图区域 Scroll into view

scrollintoview.png

24. 工作区编辑文件 Edit Files With Workspaces

工作空间使您能够将在 Chrome Devtools 中进行的更改保存到计算机上相同文件的本地副本。

进入 Sources Menu, Filesystem 下 点击 Add folder to workspace 添加要同步的工作目录

workspace

快捷键

访问 DevTools

访问 DevToolsWindowsMac
打开 Developer Tools (上一次停靠菜单)F12、Ctrl + Shift + ICmd + Opt + I
打开/切换检查元素模式和浏览器窗口Ctrl + Shift + CCmd + Shift + C
打开 Developer Tools 并聚焦到控制台Ctrl + Shift + JCmd + Opt + J

全局键盘快捷键

下列键盘快捷键可以在所有 DevTools 面板中使用:

全局键盘快捷键WindowsMac
下一个面板Ctrl + ]Cmd + ]
上一个面板Ctrl + [Cmd + [
更改 DevTools 停靠位置Ctrl + Shift + DCmd + Shift + D
打开 Device ModeCtrl + Shift + MCmd + Shift + M
切换控制台EscEsc
刷新页面F5、Ctrl + RCmd + R
刷新忽略缓存内容的页面Ctrl + F5、Ctrl + Shift + RCmd + Shift + R
在当前文件或面板中搜索文本Ctrl + FCmd + F
在所有源中搜索文本Ctrl + Shift + FCmd + Opt + F
按文件名搜索(除了在 Timeline 上)Ctrl + O、Ctrl + PCmd + O、Cmd + P
放大(焦点在 DevTools 中时)Ctrl + +Cmd + Shift + +
缩小Ctrl + -Cmd + Shift + -
恢复默认文本大小Ctrl + 0Cmd + 0
打开 command 菜单Ctrl + Shift + PCmd + Shift + P

控制台

控制台快捷键WindowsMac
上一个命令/行向上键向上键
下一个命令/行向下键向下键
聚焦到控制台Ctrl + `Ctrl + `
清除控制台Ctrl + LCmd + K
多行输入Shift + EnterShift + Enter
执行EnterReturn

后记

如果你和我一样喜欢前端,也爱动手折腾,欢迎关注我一起玩耍啊~ ❤️

github 地址,欢迎 follow 哦~

博客

我的博客,点 star,不迷路~

公众号

前端时刻

qrcode.jpg

查看原文

赞 84 收藏 56 评论 8

小林 回答了问题 · 2019-11-22

微信7.0.8浏览器 H5页面 键盘收起后界面被挡住,请问有什么解决方法?

最后发现键盘收起和跳转页面冲突到了,现在监听键盘收起一秒后,再跳页就没有问题了,但是具体什么原因却不太清楚。

关注 2 回答 2

小林 收藏了文章 · 2019-10-29

webpack4+vue打包简单入门

前言

最近在研究使用webpack的使用,在查阅了数篇文章后,学习了webpack的基础打包流程.

本来就可以一删了之了,但是觉得未免有点可惜,所以就有了这篇文章,供大家参考.

webpack打包的教程具有时效性,有不少作者在一直维护一篇文章.超过一定时间参考价值就会下降,希望各位了解这一点.

使用的依赖一览

"devDependencies": {
"clean-webpack-plugin": "^0.1.19",
"css-loader": "^1.0.0",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.4.3",
"vue-loader": "^15.4.2",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.5.17",
"webpack": "^4.19.1",
"webpack-cli": "^3.1.0",
"webpack-merge": "^4.1.4"
},
"dependencies": {
"vue": "^2.5.17"
}

都是目前最新的稳定版本.

讲解到的内容

  1. webpack的安装
  2. webpack简单配置
  3. vue的安装以及使用
  4. 使用插件
  5. 提取css
  6. 使用多个配置文件
  7. 简单的代码分离

构建目录

我们创建一个新的目录(learnwebpack).在下面创建src文件夹和一个index.html.

然后我们使用npm init命令初始化一个package.json文件,直接一路回车过去就好了.

目录结构:

  • learnwebpack

    • src
    • index.html
    • package.json

src保存我们未经编译的源码.

index.html内容如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Webpack4 && Vue</title>
</head>
<body>
    <div id="root">
        
    </div>

    <script data-original="./dist/app.bundle.js"></script>
</body>
</html>

安装webpack

在webpack4中不仅仅需要安装webpack本身,还需要安装webpack-cli.

npm install webpack webpack-cli --save-dev

使用--save-dev参数会将这两个包添加到package.json的开发依赖中.

webpack4的特性

在webpack4中可以实现0配置打包,也就是说不需要任何设置就可以完成简单的打包操作.

此外最实用的特性之一就是mode配置选项用于告诉webpack输出模式是开发还是产品,提供了已经预先定义好的常用配置.

后面的例子中我们会使用到mode.

webpack的简单配置

我们在当前目录下新建一个webpack的配置文件webpack.config.js.

此时的目录结构为:

  • learnwebpack

    • src
    • index.html
    • webpack.config.js
    • package.json

webpack.config.js的内容:

const {join:pathJoin} = require('path');
module.exports = {
    entry:{
        app:'./src/index.js' // 入口文件的位置
    },
    output:{
        filename:'[name].bundle.js', // 输出文件名字的格式
        path:pathJoin(__dirname,'./dist') // 输出的绝对路径
    },
}

为什么会有filename上的格式

对于我们当前的应用来说好像没有任何用途,打包后文件名完全可以和入口一样.

使用不同的文件名可以解决相同文件名称导致的浏览器缓存问题.

对于我们当前这个格式来说,打包后的文件名称为app.bundle.js.

此外还有一些额外的模板符号:

  • [hash] 模块标识符(module identifier)的 hash
  • [chunkhash] chunk 内容的 hash
  • [name] 模块名称
  • [id] 模块标识符(module identifier)
  • [query] 模块的 query,例如,文件名 ? 后面的字符串

现在让我们在src文件夹下新建一个index.js,只写一行简单的代码用于测试:

console.log('hello world!');

此时的目录结构为:

  • learnwebpack

    • src

      • index.js
    • index.html
    • webpack.config.js
    • package.json

为什么使用index.js

webpack4中零配置的默认入口位置就是当前配置路径下的./src/index.js,也就是说如果不指定入口的情况下也是可以打包的.

构建我们的项目

运行:

./node_modules/.bin/webpack-cli --config webpack.config.js

上方的命令有点冗长,我们使用package.json中scripts字段来定义一个快捷方式.

package.json:

{
  +++
  "scripts": {
    "build": "webpack --config webpack.config.js"
  }
  +++
}

+++ 表示package.json的其他字段,这部分目前不用关心.

现在运行这条简化的命令,效果和上方一样.

npm run build

对于npm版本高于5.2.0的同学可以尝试使用npm的附带模块npx.

npx可以直接运行./node_modules/.bin/下的内容而不必输入路径.

npx webpack --config webpack.config.js

如果操作正确你的目录下应该会多出一个dist文件夹,内部有一个app.bundle.js文件.

此时的目录结构:

  • learnwebpack

    • dist

      • app.bundle.js
    • src

      • index.js
    • index.html
    • webpack.config.js
    • package.json

我们可以运行index.html了,如果一切顺利.那么在控制台中应该会出现hello world!.

错误

当我们打包的时候webpack4会报错,原因就是我们没有指定上文中提到的mode属性,webpack默认将他设置为production.

此时如果你查看代码,就会发现代码是经过压缩的,这是webpack4的默认行为之一.

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

安装Vue

使用npm安装:

npm -i vue

vue是运行时依赖,webpack需要合适loader将vue文件解释为webpack可以理解的格式用于构建,所以我们需要vue-loader来转换vue单文件.

使用npm安装vue-loader:

npm install vue-loader --save-dev 

vue单文件中分为三个部分,其中template部分需要专用的插件进行转换.

安装vue-template-compiler:

npm install  vue-template-compiler --save-dev

这个使用vue-loader自动调用的插件,也是官方默认的,不需要任何配置.

如果你不使用他,打包的时候会报错.

简单来说他的功能是将template部分的模板转为render函数.

然后我们需要处理css,vue-loader需要css-loader才可以运行.

安装css-loader:

npm install css-loader --save-dev

css-loader的作用仅仅是将css转为webpack可以解释的类型,如果我们需要将样式使用起来插入到html中,必须使用额外的插件.

安装vue-style-loader:

npm install vue-style-loader --save-dev

vue-style-loader是由vue官方维护的你也可以使用其他的loader来处理css,他除了提供了常见的插入样式到html的功能以外还提供了其他的功能,例如热更新样式等.

修改配置

webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin'); // +++
module.exports = {
    mode:'production',
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].bundle.js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader'] // +++
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader'] // +++
            }
        ]
    },
    plugins:[
        new VueLoaderPlugin() // +++
    ]
}

需要注意的是VueLoaderPluginvue-loaderv15的版本中,这个插件是必须启用的.

修改目录结构以及文件

我们在src下创建一个pages文件夹并且在内部创建一个app.vue文件.

此时的目录结构:

  • learnwebpack

    • dist

      • app.bundle.js
    • src

      • pages

        • app.vue
      • index.js
    • index.html
    • webpack.config.js
    • package.json

app.vue文件内容:

<style>
.test > p {
  background-color: aqua;
}
</style>

<template>
    <article class="test">
        <p>{{vue}}</p>
    </article>
</template>

<script>
export default {
  data() {
    return {
      vue: "vue"
    };
  }
};
</script>

app.vue是由index.js引用的,回过头来我们修改index.js:

import Vue from 'vue'
import App from './pages/app.vue';

new Vue({
    el:'#root',
    render:h=>h(App)
})

激动人心的时候到了,如果一切顺利你的vue应用应该打包完成了,运行index.html就可以查看这个结果了.

使用插件

回顾前面的一个话题,指定输出文件名字格式.如果你将我们的内容放到一个服务器上运行,你会很容易发现一个问题.

就是缓存,web上的资源浏览器会对其进行缓存,但是对开发的时候,或者产品中的代码更新十分不友好,新的代码不会得到及时的使用.

我们让资源每次的名字不一样就可以简单的解决这个问题,接下来修改我们的webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
    +++
    output:{
        filename:'[name].[hash].js',
        path:pathJoin(__dirname,'./dist')
    },
    +++
}

此时再次修改代码打包每次的名字都不会一样.

但是出现了另外一个问题由于资源名字每次都不一致,每次我都需要手动指定index.html中引用的资源,这个时候该html-webpack-plugin出场了.

这个插件可以自动生成一个html文件,并且将资源文件按照正确顺序插入到html中.

安装html-webpack-plugin:

npm install html-webpack-plugin --save-dev

webpack.config.js添加配置

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash]].js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader']
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',// 指定模板html文件
            filename:'index.html'// 输出的html文件名称
        }),
        new VueLoaderPlugin()
    ]
}

然后我们把index.html重命名为template.html,将template.html中的script标签删除.

指定模板后HtmlWebpackPlugin会保留原来html中的内容,而且会在新生成的html文件中把script插入到合适的位置.

HtmlWebpackPlugin补充

注意:HtmlWebpackPlugin必须位于插件数组的首位.

运行项目

你会发现在dist目录下会有index.html文件,而我们打包后的index.js的输出文件名也变成了app.XXXXXXXXXXXXXXXX.js的格式,更加神奇的是在index.html中自动插入了script标签来引用打包后的js文件.

使用CleanWebpackPlugin插件

当你多次打包的时候,你会发现由于使用hash来命名输出的文件每次的文件名称都不一样,导致文件越来越多.

使用CleanWebpackPlugin可以每次构建前清空输出目录.

安装:

npm install clean-webpack-plugin --save-dev

webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require("clean-webpack-plugin");// +++
module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash]].js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader']
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',
            filename:'index.html'
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin(['dist'])// +++ 运行前删除dist目录
    ]
}

现在无论运行几次构建dist目录下都是干净的.

提取css

现在我们来将vue单文件中的css提取出来到一个单独的css文件中.

webpack4中完成这个功能的插件是mini-css-extract-plugin.

安装:

npm install mini-css-extract-plugin --save-dev

webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');// +++
module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash]].js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader // +++
                    },
                    'css-loader'
                ]
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',
            filename:'index.html'
        }),
        new MiniCssExtractPlugin({
            filename:'style.css' // 指定输出的css文件名.
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin(['dist'])
    ]
}

运行我们的项目,现在dist目录下已经有一个style.css的文件了,而且htmlwebpackplugin自动将style.css插入到了index.html中.

使用多个配置

考虑以下问题:

  • 开发的时候我们希望打包速度快,有源代码提示,有热重载(本篇文章没有涉猎)...
  • 发布产品我们希望输出的内容不会被缓存,有代码压缩...

是时候使用多个配置了,一个用于开发一个用于生产.

但是我们还可以做的更好使用webpack-merge插件,可以将多个配置合成.

安装webpack-merge:

npm install webpack-merge --save-dev

首先我们定义一个包含基本信息的webpack配置文件,这个文件被其他配置文件依赖.

webpack.common.js:

const {join:pathJoin} = require('path');
const CleanWebpackPlugin = require("clean-webpack-plugin");
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash].js',
        path:pathJoin(__dirname,'./dist')
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',
            filename:'index.html'
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin(['dist'])
    ]
}

可以看到这里定义的都是最基本的信息.

然后我们定义开发配置并且在内容使用webpack-merge插件和webpack.config.js进行合并.

webpack.dev.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'development', // 不压缩代码,加快编译速度
    devtool: 'source-map', // 提供源码映射文件调试使用
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader'] // 使用vue-style-loader直接插入到style标签中
            }
        ]
    },
})

定义生产配置.

webpack.prod.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = merge(common,{
    mode:'production', // 压缩代码
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader // 提取css到外部文件中
                    },
                    'css-loader'
                ]
            }
        ]
    },
    plugins:[
        new MiniCssExtractPlugin({
            filename:'style.css'
        })
    ]
})

最后修改一下我们package.json中的快捷方式:

+++
"scripts": {
    "dev": "webpack --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
},
+++

删除之前的webpack.config.js.

完成后的目录结构:

  • learnwebpack

    • dist
    • src

      • pages

        • app.vue
      • index.js
    • package.json
    • template.html
    • webpack.common.js
    • webpack.dev.js
    • webpack.prod.js

尝试运行npm run devnpm run build吧.

简单的代码分离

我们在index.js中引用了Vue,如果你查看打包后的代码你会发现vue本身会被打包到同一个文件中,如果我们有另外一个文件也引用了vue同样的会被打包到该文件中.

显然我们的代码依赖vue,但是vue不应该存在两份,如果可以将vue单独提取出来就好了,这个问题就是要代码分离.

在webpack4中删除了原来的CommonsChunkPlugin插件,内部集成的optimization.splitChunks选项可以直接进行代码分离.

修改webpack.dev.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'development',
    devtool: 'source-map',
    optimization:{ // +++
        splitChunks:{ // +++
            chunks:'initial' // +++ initial(初始块)、async(按需加载块)、all(全部块)

        }
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader']
            }
        ]
    },
})

我们要做的就是将打包后写入到index.html的文件从目前的一个文件拆分成多个,并且写入到index.html中.

也就是说在入口处分离代码.

运行:

npm run dev

你会发现在dist目录下多出了一个文件保存着vue,另外一个文件中保存着我们编写的代码.

参考

vue部分:

https://cn.vuejs.org/v2/guide...
https://vue-loader.vuejs.org/zh/
https://www.npmjs.com/package...

webpack部分:

https://webpack.docschina.org...
https://github.com/webpack-co...
https://github.com/jantimon/h...

参考的其他教程:

https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
http://www.cnblogs.com/anani/...
https://blog.csdn.net/bubblin...
查看原文

小林 赞了文章 · 2019-10-29

webpack4+vue打包简单入门

前言

最近在研究使用webpack的使用,在查阅了数篇文章后,学习了webpack的基础打包流程.

本来就可以一删了之了,但是觉得未免有点可惜,所以就有了这篇文章,供大家参考.

webpack打包的教程具有时效性,有不少作者在一直维护一篇文章.超过一定时间参考价值就会下降,希望各位了解这一点.

使用的依赖一览

"devDependencies": {
"clean-webpack-plugin": "^0.1.19",
"css-loader": "^1.0.0",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.4.3",
"vue-loader": "^15.4.2",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.5.17",
"webpack": "^4.19.1",
"webpack-cli": "^3.1.0",
"webpack-merge": "^4.1.4"
},
"dependencies": {
"vue": "^2.5.17"
}

都是目前最新的稳定版本.

讲解到的内容

  1. webpack的安装
  2. webpack简单配置
  3. vue的安装以及使用
  4. 使用插件
  5. 提取css
  6. 使用多个配置文件
  7. 简单的代码分离

构建目录

我们创建一个新的目录(learnwebpack).在下面创建src文件夹和一个index.html.

然后我们使用npm init命令初始化一个package.json文件,直接一路回车过去就好了.

目录结构:

  • learnwebpack

    • src
    • index.html
    • package.json

src保存我们未经编译的源码.

index.html内容如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Webpack4 && Vue</title>
</head>
<body>
    <div id="root">
        
    </div>

    <script data-original="./dist/app.bundle.js"></script>
</body>
</html>

安装webpack

在webpack4中不仅仅需要安装webpack本身,还需要安装webpack-cli.

npm install webpack webpack-cli --save-dev

使用--save-dev参数会将这两个包添加到package.json的开发依赖中.

webpack4的特性

在webpack4中可以实现0配置打包,也就是说不需要任何设置就可以完成简单的打包操作.

此外最实用的特性之一就是mode配置选项用于告诉webpack输出模式是开发还是产品,提供了已经预先定义好的常用配置.

后面的例子中我们会使用到mode.

webpack的简单配置

我们在当前目录下新建一个webpack的配置文件webpack.config.js.

此时的目录结构为:

  • learnwebpack

    • src
    • index.html
    • webpack.config.js
    • package.json

webpack.config.js的内容:

const {join:pathJoin} = require('path');
module.exports = {
    entry:{
        app:'./src/index.js' // 入口文件的位置
    },
    output:{
        filename:'[name].bundle.js', // 输出文件名字的格式
        path:pathJoin(__dirname,'./dist') // 输出的绝对路径
    },
}

为什么会有filename上的格式

对于我们当前的应用来说好像没有任何用途,打包后文件名完全可以和入口一样.

使用不同的文件名可以解决相同文件名称导致的浏览器缓存问题.

对于我们当前这个格式来说,打包后的文件名称为app.bundle.js.

此外还有一些额外的模板符号:

  • [hash] 模块标识符(module identifier)的 hash
  • [chunkhash] chunk 内容的 hash
  • [name] 模块名称
  • [id] 模块标识符(module identifier)
  • [query] 模块的 query,例如,文件名 ? 后面的字符串

现在让我们在src文件夹下新建一个index.js,只写一行简单的代码用于测试:

console.log('hello world!');

此时的目录结构为:

  • learnwebpack

    • src

      • index.js
    • index.html
    • webpack.config.js
    • package.json

为什么使用index.js

webpack4中零配置的默认入口位置就是当前配置路径下的./src/index.js,也就是说如果不指定入口的情况下也是可以打包的.

构建我们的项目

运行:

./node_modules/.bin/webpack-cli --config webpack.config.js

上方的命令有点冗长,我们使用package.json中scripts字段来定义一个快捷方式.

package.json:

{
  +++
  "scripts": {
    "build": "webpack --config webpack.config.js"
  }
  +++
}

+++ 表示package.json的其他字段,这部分目前不用关心.

现在运行这条简化的命令,效果和上方一样.

npm run build

对于npm版本高于5.2.0的同学可以尝试使用npm的附带模块npx.

npx可以直接运行./node_modules/.bin/下的内容而不必输入路径.

npx webpack --config webpack.config.js

如果操作正确你的目录下应该会多出一个dist文件夹,内部有一个app.bundle.js文件.

此时的目录结构:

  • learnwebpack

    • dist

      • app.bundle.js
    • src

      • index.js
    • index.html
    • webpack.config.js
    • package.json

我们可以运行index.html了,如果一切顺利.那么在控制台中应该会出现hello world!.

错误

当我们打包的时候webpack4会报错,原因就是我们没有指定上文中提到的mode属性,webpack默认将他设置为production.

此时如果你查看代码,就会发现代码是经过压缩的,这是webpack4的默认行为之一.

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

安装Vue

使用npm安装:

npm -i vue

vue是运行时依赖,webpack需要合适loader将vue文件解释为webpack可以理解的格式用于构建,所以我们需要vue-loader来转换vue单文件.

使用npm安装vue-loader:

npm install vue-loader --save-dev 

vue单文件中分为三个部分,其中template部分需要专用的插件进行转换.

安装vue-template-compiler:

npm install  vue-template-compiler --save-dev

这个使用vue-loader自动调用的插件,也是官方默认的,不需要任何配置.

如果你不使用他,打包的时候会报错.

简单来说他的功能是将template部分的模板转为render函数.

然后我们需要处理css,vue-loader需要css-loader才可以运行.

安装css-loader:

npm install css-loader --save-dev

css-loader的作用仅仅是将css转为webpack可以解释的类型,如果我们需要将样式使用起来插入到html中,必须使用额外的插件.

安装vue-style-loader:

npm install vue-style-loader --save-dev

vue-style-loader是由vue官方维护的你也可以使用其他的loader来处理css,他除了提供了常见的插入样式到html的功能以外还提供了其他的功能,例如热更新样式等.

修改配置

webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin'); // +++
module.exports = {
    mode:'production',
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].bundle.js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader'] // +++
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader'] // +++
            }
        ]
    },
    plugins:[
        new VueLoaderPlugin() // +++
    ]
}

需要注意的是VueLoaderPluginvue-loaderv15的版本中,这个插件是必须启用的.

修改目录结构以及文件

我们在src下创建一个pages文件夹并且在内部创建一个app.vue文件.

此时的目录结构:

  • learnwebpack

    • dist

      • app.bundle.js
    • src

      • pages

        • app.vue
      • index.js
    • index.html
    • webpack.config.js
    • package.json

app.vue文件内容:

<style>
.test > p {
  background-color: aqua;
}
</style>

<template>
    <article class="test">
        <p>{{vue}}</p>
    </article>
</template>

<script>
export default {
  data() {
    return {
      vue: "vue"
    };
  }
};
</script>

app.vue是由index.js引用的,回过头来我们修改index.js:

import Vue from 'vue'
import App from './pages/app.vue';

new Vue({
    el:'#root',
    render:h=>h(App)
})

激动人心的时候到了,如果一切顺利你的vue应用应该打包完成了,运行index.html就可以查看这个结果了.

使用插件

回顾前面的一个话题,指定输出文件名字格式.如果你将我们的内容放到一个服务器上运行,你会很容易发现一个问题.

就是缓存,web上的资源浏览器会对其进行缓存,但是对开发的时候,或者产品中的代码更新十分不友好,新的代码不会得到及时的使用.

我们让资源每次的名字不一样就可以简单的解决这个问题,接下来修改我们的webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
    +++
    output:{
        filename:'[name].[hash].js',
        path:pathJoin(__dirname,'./dist')
    },
    +++
}

此时再次修改代码打包每次的名字都不会一样.

但是出现了另外一个问题由于资源名字每次都不一致,每次我都需要手动指定index.html中引用的资源,这个时候该html-webpack-plugin出场了.

这个插件可以自动生成一个html文件,并且将资源文件按照正确顺序插入到html中.

安装html-webpack-plugin:

npm install html-webpack-plugin --save-dev

webpack.config.js添加配置

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash]].js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader']
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',// 指定模板html文件
            filename:'index.html'// 输出的html文件名称
        }),
        new VueLoaderPlugin()
    ]
}

然后我们把index.html重命名为template.html,将template.html中的script标签删除.

指定模板后HtmlWebpackPlugin会保留原来html中的内容,而且会在新生成的html文件中把script插入到合适的位置.

HtmlWebpackPlugin补充

注意:HtmlWebpackPlugin必须位于插件数组的首位.

运行项目

你会发现在dist目录下会有index.html文件,而我们打包后的index.js的输出文件名也变成了app.XXXXXXXXXXXXXXXX.js的格式,更加神奇的是在index.html中自动插入了script标签来引用打包后的js文件.

使用CleanWebpackPlugin插件

当你多次打包的时候,你会发现由于使用hash来命名输出的文件每次的文件名称都不一样,导致文件越来越多.

使用CleanWebpackPlugin可以每次构建前清空输出目录.

安装:

npm install clean-webpack-plugin --save-dev

webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require("clean-webpack-plugin");// +++
module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash]].js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader']
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',
            filename:'index.html'
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin(['dist'])// +++ 运行前删除dist目录
    ]
}

现在无论运行几次构建dist目录下都是干净的.

提取css

现在我们来将vue单文件中的css提取出来到一个单独的css文件中.

webpack4中完成这个功能的插件是mini-css-extract-plugin.

安装:

npm install mini-css-extract-plugin --save-dev

webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');// +++
module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash]].js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader // +++
                    },
                    'css-loader'
                ]
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',
            filename:'index.html'
        }),
        new MiniCssExtractPlugin({
            filename:'style.css' // 指定输出的css文件名.
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin(['dist'])
    ]
}

运行我们的项目,现在dist目录下已经有一个style.css的文件了,而且htmlwebpackplugin自动将style.css插入到了index.html中.

使用多个配置

考虑以下问题:

  • 开发的时候我们希望打包速度快,有源代码提示,有热重载(本篇文章没有涉猎)...
  • 发布产品我们希望输出的内容不会被缓存,有代码压缩...

是时候使用多个配置了,一个用于开发一个用于生产.

但是我们还可以做的更好使用webpack-merge插件,可以将多个配置合成.

安装webpack-merge:

npm install webpack-merge --save-dev

首先我们定义一个包含基本信息的webpack配置文件,这个文件被其他配置文件依赖.

webpack.common.js:

const {join:pathJoin} = require('path');
const CleanWebpackPlugin = require("clean-webpack-plugin");
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash].js',
        path:pathJoin(__dirname,'./dist')
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',
            filename:'index.html'
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin(['dist'])
    ]
}

可以看到这里定义的都是最基本的信息.

然后我们定义开发配置并且在内容使用webpack-merge插件和webpack.config.js进行合并.

webpack.dev.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'development', // 不压缩代码,加快编译速度
    devtool: 'source-map', // 提供源码映射文件调试使用
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader'] // 使用vue-style-loader直接插入到style标签中
            }
        ]
    },
})

定义生产配置.

webpack.prod.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = merge(common,{
    mode:'production', // 压缩代码
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader // 提取css到外部文件中
                    },
                    'css-loader'
                ]
            }
        ]
    },
    plugins:[
        new MiniCssExtractPlugin({
            filename:'style.css'
        })
    ]
})

最后修改一下我们package.json中的快捷方式:

+++
"scripts": {
    "dev": "webpack --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
},
+++

删除之前的webpack.config.js.

完成后的目录结构:

  • learnwebpack

    • dist
    • src

      • pages

        • app.vue
      • index.js
    • package.json
    • template.html
    • webpack.common.js
    • webpack.dev.js
    • webpack.prod.js

尝试运行npm run devnpm run build吧.

简单的代码分离

我们在index.js中引用了Vue,如果你查看打包后的代码你会发现vue本身会被打包到同一个文件中,如果我们有另外一个文件也引用了vue同样的会被打包到该文件中.

显然我们的代码依赖vue,但是vue不应该存在两份,如果可以将vue单独提取出来就好了,这个问题就是要代码分离.

在webpack4中删除了原来的CommonsChunkPlugin插件,内部集成的optimization.splitChunks选项可以直接进行代码分离.

修改webpack.dev.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'development',
    devtool: 'source-map',
    optimization:{ // +++
        splitChunks:{ // +++
            chunks:'initial' // +++ initial(初始块)、async(按需加载块)、all(全部块)

        }
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader']
            }
        ]
    },
})

我们要做的就是将打包后写入到index.html的文件从目前的一个文件拆分成多个,并且写入到index.html中.

也就是说在入口处分离代码.

运行:

npm run dev

你会发现在dist目录下多出了一个文件保存着vue,另外一个文件中保存着我们编写的代码.

参考

vue部分:

https://cn.vuejs.org/v2/guide...
https://vue-loader.vuejs.org/zh/
https://www.npmjs.com/package...

webpack部分:

https://webpack.docschina.org...
https://github.com/webpack-co...
https://github.com/jantimon/h...

参考的其他教程:

https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
http://www.cnblogs.com/anani/...
https://blog.csdn.net/bubblin...
查看原文

赞 26 收藏 15 评论 6

认证与成就

  • 获得 3 次点赞
  • 获得 16 枚徽章 获得 0 枚金徽章, 获得 4 枚银徽章, 获得 12 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-11-28
个人主页被 313 人浏览