为何要写这篇文章?由于今天掘金的早报有一篇关于 Webpack 的入门的文章,读完以后发现本身确实该学习一下 Webpack 了,因此有了这篇文章。
我对于 webpack 的了解仅限于在 vue-cli 中接触过,固然都是现成的,本身也从没操做过。
可是随着本身的成长,这些必需要了解一下,接下来简单都构建一个属于本身的 webpack 打包工具...css
我在初次学习新东西的时候,都会先先弄懂三个问题:html
在 webpack 文档中是这样定义的:vue
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序须要的每一个模块,而后将全部这些模块打包成一个或多个 bundle。node
配合其官网的首页图不难理解其含义:一切文件如:JavaScript 、CSS 、 SASS 、 IMG/PNG等,在 Webpack 眼中都是一个个模块,经过对 Webpack 进行配置,对模块进行组合和打包。通过 Webpack 的处理,最终会输出浏览器能使用的静态资源。react
基本理解了什么是 Webpack 、能干什么以后,接下来就开始理一下如何使用它。 顺着 Webpack 的文档学习,在正式使用以前,它须要咱们理解几个核心概念:webpack
entry 是配置模块的入口,它指示 Webpack 执行构建的第一步。
能够在配置文件中配置 entry 属性,来指定一个或多个入口点git
entry 类型有三种:字符串、数组、对象。es6
output 配置如何输出最终想要的代码。output 是一个 object,里面包含一系列配置项。github
module 配置如何处理模块web
Loader 能够看做具备文件转换功能的翻译员,配置里的 module.rules 数组配置了一组规则,告诉 Webpack 在遇到哪些文件时使用哪些 Loader 去加载和转换。
Plugin 用于扩展 Webpack 功能,各类各样的 Plugin 几乎让 Webpack 能够作任何构建相关的事情。
Plugin 的配置很简单,plugins 配置项接受一个数组,数组里每一项都是一个要使用的 Plugin 的实例,Plugin 须要的参数经过构造函数传入。
固然使用 Plugin 的难点在于掌握 Plugin 自己提供的配置项,而不是如何在 Webpack 中接入 Plugin。
想实现某项 Webpack 没有的功能去 gayHub 碰碰运气吧!哦不,是 github 碰碰运气吧!
Chunk,代码块,即打包后输出的文件。
Webpack 会为每一个 Chunk 取一个名称,能够根据 Chunk 的名称来区分输出的文件名。
filename: '[name].js'
复制代码
一个入口文件,默认 chunkname 为 main。 除了内置变量 name,与 chunk 相关的变量还有:
了解了基本概念就直接开车吧,咳咳咳,开始实战。
// ./webpack.config.js
module.exports = {
mode: 'development',
entry:{
app1: './src/index.js',
app2: './src/main.js'
},
output: {
path: __dirname + '/dist',
filename: '[hash][name].js'
},
module: {
rules: [
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/
}
]
}
};
// ./src/index.css
html {
background: #333;
color: #fff;
}
// ./src/index.js
import './index.css'
const sleep = async time => await new Promise( resolve => {
setTimeout( () => {
console.log(`等待${time}s`)
return resolve
}, time*1000)
} )
sleep(5)
console.log(`Success!`)
// ./src/main.js
const sleep = async time => await new Promise( resolve => {
setTimeout( () => {
console.log(`等待${time}s`)
return resolve
}, time*1000)
} )
sleep(2)
// .babelrc
{
"presets": [
"es2015",
"stage-0"
],
"plugins": [
["transform-runtime", {
"polyfill": false,
"regenerator": true
}]
]
}
// package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"dependencies": {
"babel-core": "^6.26.3",
"babel-polyfill": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^0.28.11",
"style-loader": "^0.21.0",
"webpack": "^4.8.3",
"webpack-cli": "^2.1.3"
},
"devDependencies": {
"babel-loader": "^7.1.4",
"babel-plugin-transform-runtime": "^6.23.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Aditya",
"license": "ISC"
}
复制代码
上述代码是我写的第一个 webpack demo,入门是真的简单,因此很快的根据文档配置了一个可以打包 css、es六、async/await 的 Webpack。
其中一些依赖项的安装以下
// npm i -D 是 npm install --save-dev 的简写
npm i -D webpack webapck-cli
npm i -D css-loader style-loader
npm i -D babel-loader babel-core babel-polyfill babel-preset-es2015 babel-preset-stage-0 babel-plugin-transform-runtime
复制代码
在配置过程当中遇到的问题:css代码被打包了,却没有生效。
一开始在配置 Loader 中,我只写了 css-loader,由于今天看的博文中的栗子就只写 css-loader , 却不知人家根本就没写任何 CSS 样式=。=
因此善用了一下手中的搜索引擎,从而得知这个过程应该是这样的:
Webpack 在遇到以 .css 结尾的文件时先使用 css-loader 读取 CSS 文件,再交给 style-loader 把 CSS 内容注入到 JavaScript 里。
style-loader 的工做原理大概是这样的:把 CSS 内容用 JavaScript 里的字符串存储起来, 在网页执行 JavaScript 时经过 DOM 操做动态地往 head 标签里插入 style 标签。
了解 ES 6 的同窗都应该知道,目前部分浏览器和 Node.js 已经支持 ES6,但因为它们对 ES6 全部的标准支持不全,这致使在开发中不敢全面地使用 ES6。 一般咱们须要把采用 ES6 编写的代码转换成目前已经支持良好的 ES5 代码,这包含两件事:
Babel 能够方便的完成以上2件事。 Babel 是一个 JavaScript 编译器,能将 ES6 代码转为 ES5 代码,让你使用最新的语言特性而不用担忧兼容性问题,而且能够经过插件机制根据需求灵活的扩展。
在 Babel 执行编译的过程当中,会从项目根目录下的 .babelrc 文件读取配置。.babelrc 是一个 JSON 格式的文件,内容大体以下:
{
"presets": [
"es2015",
"stage-0"
],
"plugins": [
["transform-runtime", {
"polyfill": false,
"regenerator": true
}]
]
}
复制代码
babel-loader 是必须的,在 Webpack 经过 Loader 接入 Babel,完成转码
presets 属性告诉 Babel 要转换的源码使用了哪些新的语法特性,一个 Presets 对一组新语法特性提供支持,多个 Presets 能够叠加。 Presets 实际上是一组 Plugins 的集合,每个 Plugin 完成一个新语法的转换工做。
3.为了支持一些特定应用场景下的语法,和 ECMAScript 标准没有关系,例如 babel-preset-react 是为了支持 React 开发中的 JSX 语法。
Plugin 属性告诉 Bable 要使用那些插件,插件能够控制如何转换代码。
官方给出的定义是: babel-plugin-transform-runtime 是 Babel 官方提供的一个插件,做用是减小冗余代码。 可是咱们为何要使用它?主要是由于使用 ES 7 的 async 函数。
由于 runtime 编译器插件作了如下三件事:
该插件的具体信息:transform-runtime
至于 babel 的其余的具体用法,能够查阅 Babel官方文档
对于 Webpack 第一步学习就到这里结束了,翻阅的资料有点多,须要学习的东西太多了,一时半会也记不住,算是铺个路吧,但愿从此的学习可以顺畅一些。 欢迎大佬指点不足之处。