webpack已成为现代Web开发中最重要的工具之一。它是一个用于JavaScript的模块打包工具,但是它也可以转换所有的前端资源,例如HTML和CSS,甚至是图片。它可以让你更好地控制应用程序所产生的HTTP请求数量、允许你使用其他资源的特性(例如Jade、Sass和ES6)。webpack还可以让你轻松地从npm下载包。

本文主要针对那些刚接触webpack的同学,将介绍初始设置和配置、模块、加载器、插件、代码分割和热模块替换。

在继续学习下面的内容之前需要确保你的电脑中已经安装了Node.js。

初始配置

使用npm初始化一个新项目并安装webpack:

mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack@beta --save-dev
mkdir src
touch index.html src/app.js webpack.config.js

编写下面这些文件:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>Hello webpack</title></head><body><div id="root"></div><script src="dist/bundle.js"></script></body>
</html>
// src/app.js
const root = document.querySelector('#root')
root.innerHTML = `<p>Hello webpack.</p>`
// webpack.config.js
const webpack = require('webpack')
const path = require('path')const config = {context: path.resolve(__dirname, 'src'),entry: './app.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js'},module: {rules: [{test: /\.js$/,include: path.resolve(__dirname, 'src'),use: [{loader: 'babel-loader',options: {presets: [['es2015', { modules: false }]]}}]}]}
}module.exports = config

上面的配置是一个普通的出发点,它通知webpack将入口文件src/app.js编译输出到文件/dist/bundle.js中、使用babel将所有的.js文件从ES2015转换成ES5。

为了让它可以转换到ES5格式的JS文件,我们需要安装三个包:babel-core、webpack加载器babel-loader和预置babel-preset-es2015。使用{ modules: false }让Tree Shaking 从打包文件中删除未使用的导出项(exports)以减少文件大小。

npm install babel-core babel-loader babel-preset-es2015 --save-dev

最后,用以下内容替换package.jsonscripts部分:

"scripts": {"start": "webpack --watch","build": "webpack -p"
},

在命令行中运行npm start将以监视模式启动webpack,当src目录中的.js文件更改时,它将重新编译bundle.js。控制台中的输出展示了打包文件的信息,注意打包文件的数量和大小十分重要。

现在当你在浏览器中加载index.html页面时会看到"Hello webpack."。

open index.html

打开dist/bundle.js文件看看webpack都做了哪些事情,顶部是webpack的模块引导代码,底部是我们的模块。到目前为止,你可能对于这个还没有一个深刻的印象。但是现在你可以开始编写ES6模块,webpack将生成适用于所有浏览器的打包文件。

使用Ctrl + C停止webpack,运行npm run build以生产模式编译我们的bundle.js

注意,打包文件的大小从2.61 kB减少到了585字节。再看一下dist/bundle.js文件,你会看到大量难懂的代码,因为我们使用UglifyJS压缩了它。这样的话,我们可以使用更少的代码达到与之前一样的效果。

模块

优秀的webpack知道如何使用各种格式的JavaScript模块,最著名的两个是:

  • ES2015 import语句
  • CommonJS require()语句

我们可以通过安装、导入lodash来测试这些格式的模块。

npm install lodash --save
// src/app.js
import {groupBy} from 'lodash/collection'const people = [{manager: 'Jen',name: 'Bob'
}, {manager: 'Jen',name: 'Sue'
}, {manager: 'Bob',name: 'Shirley'
}, {manager: 'Bob',name: 'Terrence'
}]
const managerGroups = groupBy(people, 'manager')const root = document.querySelector('#root')
root.innerHTML = `<pre>${JSON.stringify(managerGroups, null, 2)}</pre>`

运行npm start启动webpack并刷新index.html,你可以看到一个根据manager分组的数组。

让我们将这个数组转移到它自己的模块people.js中。

// src/people.js
const people = [{manager: 'Jen',name: 'Bob'
}, {manager: 'Jen',name: 'Sue'
}, {manager: 'Bob',name: 'Shirley'
}, {manager: 'Bob',name: 'Terrence'
}]export default people

我们可以在app.js中使用相对路径轻松的导入它。

// src/app.js
import {groupBy} from 'lodash/collection'
import people from './people'const managerGroups = groupBy(people, 'manager')const root = document.querySelector('#root')
root.innerHTML = `<pre>${JSON.stringify(managerGroups, null, 2)}</pre>`

注意:像lodash/collection这样没有相对路径的导入是导入安装在/node_modules的模块,你自己的模块需要一个类似./people的相对路径,你可以以此区分它们。

加载器

我们已经介绍过,你可以通过配置像babel-loader这样的加载器来告诉webpack在遇到不同文件类型的导入时该怎么做。你可以将多个加载器组合在一起,应用到很多文件转换中。在JS中导入.sass文件是一个非常的例子。

Sass

这种转换涉及三个单独的加载器和node-sass库:

npm install css-loader style-loader sass-loader node-sass --save-dev

在配置文件中为.scss文件添加新规则。

// webpack.config.js
rules: [{test: /\.scss$/,use: ['style-loader','css-loader','sass-loader']
}, {// ...
}]

注意: 任何时候更改webpack.config.js中的任意一个加载规则都需要使用Ctrl + Cnpm start重新启动构建。

加载器序列以相反的顺序进行处理:首先sass-loader 将Sass转换为CSS;然后css-loader 将CSS解析为JavaScript并解析所有依赖;最后style-loader将我们的CSS输出到文档中的

你可以将它们看作函数调用,将一个加载器的输出输入到下一个加载器中。

styleLoader(cssLoader(sassLoader('source')))

添加一个sass源文件:

/* src/style.scss */
$bluegrey: #2B3A42;pre {padding: 20px;background: $bluegrey;color: #dedede;text-shadow: 0 1px 1px rgba(#000, .5);
}

你现在可以直接在JavaScript中导入Sass文件。

// src/app.js
import './style.scss'// ...

重新加载index.html,你应该会看到一些样式。

JS中的CSS

我们刚刚在JavaScript中将一个sass文件作为模块导入了。

打开dist/bundle.js并搜索“pre {”。事实上,我们的sass已被编译成一串CSS,并作为一个模块保存在我们的打包文件中。当我们将这个模块导入JavaScript中时,style-loader会将这个字符串输入到嵌入的<style>标签中。

我知道你在想什么---为什么?

我不会在这里过多的讨论这个问题,但这里有几个值得了解的原因:

  • 你想要包含在项目中的JavaScript组件可能依赖于其他资源才能正常运行(HTML,CSS,图片,SVG),如果这些资源都可以打包在一起,那么导入和使用将会更容易。
  • 消除死代码:当你的代码不再导入JS组件时,CSS也将不再被导入。生成的打包文件将只会包含执行某些操作的代码。
  • CSS模块:CSS的全局命名空间很难保证对CSS的更改不会产生任何副作用。CSS模块通过将CSS默认设置为本地命名空间、提供可以在JavaScript中引用的唯一类名来更改这一模式。
  • 通过打包、分割代码等巧妙的方式来减少HTTP请求的数量。

图片

加载器的最后一个例子是使用url-loader处理图片。

在标准的HTML文档中,当浏览器遇到<img>标签或具有background-image属性的元素时将请求图片。你可以使用webpack将图片存储为JavaScript字符串来对小图片进行优化处理。这样你就可以预先加载它们,并且浏览器不必在以后为其单独发起请求。

npm install file-loader url-loader --save-dev

添加一个加载图片的规则:

// webpack.config.js
rules: [{test: /\.(png|jpg)$/,use: [{loader: 'url-loader',options: { limit: 10000 } // 将大小小于10kb的图片转为base64字符串}]
}, {// ...
}]

使用Ctrl + Cnpm start重新启动构建。

运行下面的命令下载测试图片:

curl https://raw.githubusercontent.com/sitepoint-editors/webpack-demo/master/src/code.png --output src/code.png

现在可以在app.js的顶部导入图片:

// src/app.js
import codeURL from './code.png'
const img = document.createElement('img')
img.src = codeURL
img.style.backgroundColor = "#2B3A42"
img.style.padding = "20px"
img.width = 32
document.body.appendChild(img)// ...

这样将引入一个图片,其中src属性包含图片本身的数据URL。

<img src="https://img-blog.csdnimg.cn/2022010622584449603.png" style="background: #2B3A42; padding: 20px" width="32">

此外,由于css-loader保障了使用url()引用的图片也可以通过url-loader运行,所以可以直接在CSS中内联它。

/* src/style.scss */
pre {background: $bluegrey url('code.png') no-repeat center center / 32px 32px;
}

编译成这样:

pre {background: #2b3a42 url("https://img-blog.csdnimg.cn/2022010622584449603.png") no-repeat scroll center center / 32px 32px;
}

静态资源模块

你现在应该可以明白加载器是如何建立各种资源之间的依赖关系的。
这其实也就是webpack主页上的图片所展示的那样:

虽然JavaScript是入口点,但是webpack认为其他类型资源(如HTML,CSS和SVG)都有自己的依赖关系,所以这些类型的资源应该被视为构建过程的一部分。

posted @ 2017-11-24 10:08 间阳幕宾 阅读(...) 评论(...) 编辑 收藏
刷新评论刷新页面返回顶部

公告

Copyright ©2019 间阳幕宾
Happy life,Happy Coding!

一份关于webpack2和模块打包的新手指南(一)相关推荐

  1. 自己的模块给其他人调用是怎么打包的_webpack实战——模块打包

    写在前面 这是webpack实战系列的第二篇:模块和模块打包.上一篇:webpack实战--打包第一个应用 记录了webpack的一些基础内容与一个简单的小例子,开启了webpack的实战之路,这一篇 ...

  2. JavaScript模块打包器rollup

    学习资料:拉勾课程<大前端高薪训练营> 阅读建议:搭配文章的侧边栏目录进行食用,体验会更佳哦. 内容说明:本文不做知识点的搬运工,技术详情请查看官方文档. 一:认识rollup rollu ...

  3. springboot多模块打包指定子模块环境配置文件

    springboot多模块打包指定子模块环境配置文件 父pom.xml maven 命令:mvn clean package -Dmaven.test.skip=true -P uat 命令解析:清c ...

  4. 指定模块打包命令_大前端进阶之Babel、模块化、webpack

    Babel 什么是Babel? 很多ES6高级语法浏览器是不支持的,Node.js也不一定能够运行,这时就需要使用转码器了. Babel是一个使用非常广泛的转码器,它可以将ES6语法代码转换为ES5语 ...

  5. 多模块打包后,扫描不到@controller和@service,实现 ADD DIRECTORY ENTRIES

    多模块打包后,扫描不到@controller和@service等Bean. 原因:打包时没有生成目录信息 解决办法: 1.在eclipse或者myeclipse 打包时 勾选 ADD DIRECTOR ...

  6. vue 分模块打包 脚手架_vue-cli分模块独立打包

    基于vue-cli3多模块独立打包 一.目标 我们要实现什么? 所谓分模块打包,也可以说一个项目一个模块,理解: 在src目录下,多个项目共用一些数据方法,但是每个项目有自己独立的入口文件,路由文件, ...

  7. springboot公共模块打包_解决SpringBoot多模块发布时99%的问题?

    每天都会分享Java架构文章,喜欢的朋友关注我.ps:文末有彩蛋,惊喜等着你 如果使用的是 SpringBoot 多模块的项目,在发布的时候可能遇到各种各样的问题.本文归纳了以下 8 个原则和发布时经 ...

  8. Zepto自定义模块打包构建

    首先clone下zepto的git源代码: git clone https://github.com/madrobby/zepto.git 复制代码 进入到 zepto 文件夹下 下载相关依赖包 np ...

  9. 模块打包之CommonJS与ES6模块比较初探

    Time: 20190920 模块是具有特定功能的组成单元,不同模块负责不同的工作,然后会以某种方式联系到一起,形成完整的程序逻辑. CommonJS CommonJS是2009年社区提出的,包含模块 ...

  10. Maven多模块打包成war+vue打包

    Maven多模块打包成war+vue打包 Maven多模块打包成war 示例 对于这样的工程, 1.需要将总的maven工程进行pom打包 <groupId>**</groupId& ...

最新文章

  1. 【ACM】UVA - 340 Master-Mind Hints(一定要好好学英语...)
  2. 美国没有光刻机背后的原因
  3. HTML5——FileReader详解
  4. eclipse创建了java web项目后怎么连接mysql
  5. 评职称不需英语计算机的文件,《关于重申专业技术人员职称评定、职务聘任必须坚持外语、计算机条件的通知》……...
  6. brew 更换国内源(镜像)
  7. 随笔② Java中的关键字 --- final关键字
  8. Powerdesigner 在线打开 不用安装客户端 访问pdm,ldm文件
  9. 深入探讨用位掩码代替分支(3):VC6速度测试
  10. 现代计算机网络的6个方面的应用,现代计算机网络技术应用及发展(共4384字).doc...
  11. 对PostgreSQL cmin和cmax的理解
  12. 华为鸿蒙热水器,美的华为跨界联合!搭载鸿蒙OS的美的产品双11上市
  13. dll模块化设计与编程_FPGA设计原则经验分享
  14. 【多题合集】线段覆盖1、2、3
  15. “现有人工智能都是二流的”
  16. 面经——Linux使用
  17. c#使用Transactions类完成多个数据库的事务操作(分布式事务处理)
  18. 项目日报模板_速看!贵港这个年产值近100亿元项目即将正式投产
  19. assignment to ‘float *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]指针类型错
  20. Qt程序退出QThread: Destroyed while thread is still running问题

热门文章

  1. 纯css写图形 优惠券
  2. 大数据和数据挖掘是什么关系?
  3. html根据出生日期计算星座,星座测算.html
  4. 探索汽车行业大数据应用
  5. 电动阀门和气动阀门有什么区别
  6. 如何修改ns服务器,Godaddy如何修改NS信息
  7. 超轻量98点人脸关键点检测
  8. PDF文件双面打印设置
  9. 计算机无法识别打印机usb,USB无法识别打印机的解决方案和教程
  10. web前端人事面试常问问题