一小时上手webpack(基础使用指南含demo)

一、什么是webpack

官方定义:

webpack is a module bundler lets you write any module format(mixed also), compiles then for the browser. And it supports static async bundling.

简单的说webpack是一个构建工具,什么是构建工具呢,我们在开发环境的代码,是为了方便阅读与开发,生产环境的代码则是为了代码更好的运行。开发环境的代码,要进行压缩编译以后,才能放在线上执行,这样代码体积更小,加载起来更快,所以构建工具一般有以下几种作用:

1、代码压缩

将JS、CSS代码混淆压缩,让代码体积更小,加载更快

2、编译语法

编写CSS时使用Less、Sass,编写JS时使用ES6、TypeScript等,这些标准目前都无法被浏览器兼容,因此需要构建工具编译,例如使用Babel编译ES6语法。

3、处理模块化:

CSS和JS的模块化语法,目前都无法被浏览器兼容。因此开发环境可以使用既定的模块化语法,但是需要构建工具将模块化语法编译为浏览器可识别形式。例如使用webpack、Rollup等处理JS模块化。


webpack-1556266977481.png

二、why webpack

模块化

之前写过一篇关于模块化的文章,不管是AMD还是CMD,都是runtime的时候进行的,且浏览器的支持性还不是特别好,需要一个东西来进行转化。

loader

一个web不止有js,还有css和各种静态资源,webpack提供了各种loader来处理css和less、sass。

转载一个关于webpack诞生的故事:

2012年,一个叫做Tobias的,在Newberg(美国一个城市)读master的德国人要写一片学位论文。他之前是写c#的,从来没有写过一个web界面。他在一些特定的场景需要用到Google Web Toolkit中的一个叫做code splitting的功能。而在他的论文中他需要写一个web app,他就想找一个包含这个功能的库来用。他找到的这个库叫webmake,这也是一个bundler。但是却没有code splitting这个功能,于是他提了一个issue,并且写了一堆如何实现这个功能的代码,希望维护者能够加入这个功能。在一番讨论过后维护者拒绝了他,于是在经过同意之后,他把这个库fork到了了过去并自己加上了这个功能,给新的库取名为webpack。

2014年,Dan Abramov在Stack Overflow上提了一个关于hot module replacement的问题,Tobias用很大的篇幅给他介绍了这个还在开发的功能,详细解释了这个功能怎么在webpack里工作的,以及这个功能有多棒,你可以不用刷新浏览器了!

2015年,这时在Instagram工作的Pete Hunt通过一次演讲告诉了世界他们是如何使用webpack打包发布他们的react app的。然后你懂得,webpack就火了。像Facebook这样的公司也开始使用webpack了。但是其实Tobias只是每周大概花5 6个小时在webpack中。

是的,在这两个讨论中,webpack彻底火了,走向了世界。

三、搭建环境

创建项目

创建一个项目目录并生成 package.json。npm 使用它来管理项目依赖项。以下是基本命令:

mkdir webpack-demo

cd webpack-demo npm init -y

安装 Webpack

npm install webpack webpack-cli --save-dev

运行webpack

在src目录下新建一个index.js

console.log(111)

执行命令:

webpack

自动会生成一个dist文件夹,main.js里面会生成一个

console.log(111)

四、配置 html-webpack-plugin

可以借助html-webpack-plugin来新建一个HTML文件在浏览器看效果

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

新建一个webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Webpack demo'
    })
  ]
}

修改index.js

document.write('你好世界!!!')

执行命令:webpack,会看到dist文件下会多出来一个index.html,在浏览器打开index.html就出现熟悉的页面了

五、配置webpack-dev-server

WDS 是在内存中运行的开发服务器,这意味着打包内容不会写入文件而是存储在内存中。这一区别在调试代码和样式时非常重要。

默认情况下,WDS 会在您开发应用程序时自动在浏览器中刷新内容,因此您无需亲自执行此操作。但它也支持高级 Webpack 功能——热模块更换(HMR)。

安装

npm install webpack-dev-server --save-dev

配置

我们需要用npm script来启动他,按照npm的约定,我们定义一个命令,在package.json文件里面:

"scripts": {
  "start": "webpack-dev-server --mode development",
  "build": "webpack --mode production"
},

这肯定是非常眼熟了,我们在使用vue-cli的时候一定会有类似的命令

启动

正常情况下,输入命令npm start或者npm run start就可以启动项目了

但是一般情况下都会报这个错,因为webpack和WDS对于版本的兼容性要求很高,这一点也非常的恶心

[图片上传失败...(image-197bda-1610333237812)]

我的解决方案是在package.json文件里面:

"webpack": "^4.17.1",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.2"

然后重新npm install,再次启动项目就好了

如果你尝试修改代码,你应该会在终端里看到一些输出信息。浏览器也会根据变动做一些强制更新。

基础配置 WDS

webpack.config.js

devServer: {
    // 仅显示错误级别的输出,从而减少输出信息
    stats: "errors-only",

    // 从环境变量中传入 host 和 port,从而达到可配置
    //
    // 如果你使用 Docker, Vagrant 或者 Cloud9, 那么把
    // host 设置为 "0.0.0.0";
    //
    // 0.0.0.0 对于所有的网络设备都是可用的
    // 而默认的 `localhost` 不行.
    host: process.env.HOST, // 默认为 `localhost`
    port: process.env.PORT, // 默认为 8080
    open: true, // 在浏览器中打开
},

通过网络访问开发服务器

webpack.config.js

host: '0.0.0.0',

package.json

"start": "webpack-dev-server --host 0.0.0.0 --mode development",

此时启动以后就可以用过本机IP地址访问本地服务了

修改配置文件热更新

当打包文件发生变化时,开发服务器会自动重启;但是,当 Webpack 配置变化了呢?如果说,每次配置变动你就要手动重启开发服务器,没过一会儿,你就会厌烦不堪了。如 GitHub 中所讨论的那样,我们可以使用 nodemon 监视工具自动执行该过程。

安装nodemon

npm install nodemon --save-dev

package.json

"start": "nodemon --watch webpack.config.js --host 0.0.0.0 --exec \"webpack-dev-server --mode development\"",

轮询而不是监测文件

这个选项适合有时候热更新不管用了,可以试一下这个选项,基本都能解决

devServer: {
    watchOptions: {
      // 首次更改后延迟多少时间再重新构建
      aggregateTimeout: 300,

      // 轮询的时间间隔 (单位 ms, 接受 Boolean 类型的值)
      poll: 1000,
    },
},

六、Webpack Dev Middleware

webpack-dev-middleware是一个包装程序,它将通过webpack处理的文件发送到服务器。它在webpack-dev-server内部使用,但是如果需要,它可以作为单独的软件包使用,以允许进行更多自定义设置。我们将看一个webpack-dev-middleware与Express服务器结合的示例。

安装

npm install --save-dev express webpack-dev-middleware

webpack.config.js的output新增一个输出地址

module.exports = {
  devServer: {
    // 仅显示错误级别的输出,从而减少输出信息
    stats: "errors-only",

    // 从环境变量中传入 host 和 port,从而达到可配置
    //
    // 如果你使用 Docker, Vagrant 或者 Cloud9, 那么把
    // host 设置为 "0.0.0.0";
    //
    // 0.0.0.0 对于所有的网络设备都是可用的
    // 而默认的 `localhost` 不行.
    host: '0.0.0.0', // 默认为 `localhost`
    port: process.env.PORT, // 默认为 8080
    useLocalIp: true,
    open: false, // 在浏览器中打开
    watchOptions: {
        // 首次更改后延迟多少时间再重新构建
        aggregateTimeout: 300,

        // 轮询的时间间隔 (单位 ms, 接受 Boolean 类型的值)
        poll: 1000,
    },
  },
  output: {
    publicPath: '/',
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Webpack demo'
    })
  ]
}

新建一个server.js

const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');

const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);

// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(
  webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
  })
);

// Serve the files on port 3000.
app.listen(3000, function () {
  console.log('Example app listening on port 3000!\n');
});

package.json加一个命令

"scripts": {
    "start": "nodemon --watch webpack.config.js --host 0.0.0.0 --exec \"webpack-dev-server --mode development\"",
    "build": "webpack --mode production",
    "server": "node server.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

运行

npm run server

在localhost:3000就可以看到输出的服务了

记在最后

webpack内容非常多,接下来还会继续记录loader和分包加载以及各种插件

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • Webpack 第一章 Webpack 简介 Instagram团队在进行前端开发的过程中,发现当项目组成员越来越...
    whitsats阅读 622评论 0 1
  • [toc] learn webpack4 webpack 用于编译 JavaScript 模块。 本质上,webp...
    heyi_let阅读 618评论 0 1
  • 一、webpack 配置 1. 资源入口 Webpack 通过 context 和 entry 这两个配置项来共同...
    了凡和纤风阅读 937评论 0 7
  • 模块化 CommonJS CommonJS是一种使用广泛的 JavaScript模块化规范,核心思想是通过 req...
    小小的白菜阅读 580评论 0 12
  • 推荐指数: 6.0 书籍主旨关键词:特权、焦点、注意力、语言联想、情景联想 观点: 1.统计学现在叫数据分析,社会...
    Jenaral阅读 5,685评论 0 5