开篇一张图,内容全靠编。一张图直接明了的说明了webpack的作用,bundle your sytles/assets/scripts/images。
webpack中文官网:https://www.webpackjs.com/ 官方网站永远都是我们最好的学习途径
1 安装webpack 和 webpack-cli
npm install webpack webpack-cli --save-dev
详见安装指南:https://www.webpackjs.com/guides/getting-started/
2、配置webpack.config.js
新建一个配置文件 :webpack.config.js 。输入一下代码:
const path = require('path')
module.exports = {
entry:'./src/index.js',
output:{
path:path.resolve(__dirname,'release'),
filename:'bundle.js'
}
}
3 配置packpage.js
在packpage.js->scripts 中添加一行来运行webpack命令。运行: npm run dev 就可以在relesae中生成bundle.js文件了。
"dev":"webpack --config ./webpack.config.js --mode development"
4 安装HtmlWebpackPlugin插件
npm install html-webpack-plugin --save-dev
在我们构建之前,你应该了解,虽然在
dist/
文件夹我们已经有index.html
这个文件,然而HtmlWebpackPlugin
还是会默认生成index.html
文件。这就是说,它会用新生成的index.html
文件,把我们的原来的替换。如果你在代码编辑器中将index.html
打开,你就会看到HtmlWebpackPlugin
创建了一个全新的文件,所有的 bundle 会自动添加到 html 中。
看了上面这段文字你就明白了这个插件的意义了吧。为了更好的演示该插件我们需要再写一个js文件,并在index.js中引入它。
//print.js
export default function printMe() {
console.log('I get called from print.js!');
}
//index.js
import printMe from './print.js'
printMe()
所以我们需要再次去修改我们的webpach.config.js文件。这次入口有两个文件index.js 和 print.js。app和print 算是别名吧。所以output也需要修改。[name].bundle.js,这就会根据别名生成两个独立的bundle文件了。关于plugins有很多配置项,这里只配置了一个title,可以直接配置一个html模板。
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry:{
app:'./src/index.js',
print:'./src/print.js'
},
output:{
path:path.resolve(__dirname,'dist'),
filename:'[name].bundle.js'
},
plugins:[
new HtmlWebpackPlugin({
title: 'Output Management'
//template:'./index.html' //使用模板就必须提前 建好模板文件
})
],
}
运行 npm run dev 会在dist目录下面生成三个文件,其中index.html里面也自动引入了生成的两个js文件。不需要我们在去手动配置了。
我们在index.js中已经引入了print.js,在打包生成的index.bundle.js中就会包含 print.js中的代码。所以在entry中没有必要再写一个print: './src/print.js'了。entry对象中的js会自动插入index.html的body中,这样会重复添加了,这应该是官方文档的一个小失误吧。如果两个js文件没有关联,则可以在entry中加入。
代码重复编译的问题在大型项目中是个不可忽视的问题,因此官方提供了一种解决方法叫代码分离。
代码分离是 webpack 中最引人注目的特性之一。此特性能够把代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。代码分离可以用于获取更小的 bundle,以及控制资源加载优先级,如果使用合理,会极大影响加载时间。
有三种常用的代码分离方法:
- 入口起点:使用
entry
配置手动地分离代码。 - 防止重复:使用
CommonsChunkPlugin
去重和分离 chunk。 - 动态导入:通过模块的内联函数调用来分离代码。
你可能已经注意到,由于过去的指南和代码示例遗留下来,导致我们的 /dist
文件夹相当杂乱。webpack 会生成文件,然后将这些文件放置在 /dist
文件夹中,但是 webpack 无法追踪到哪些文件是实际在项目中用到的。
通常,在每次构建前清理 /dist
文件夹,是比较推荐的做法,因此只会生成用到的文件。让我们完成这个需求。
clean-webpack-plugin
是一个比较普及的管理插件,让我们安装和配置下。
npm install clean-webpack-plugin --save-dev
修改webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
entry:{
app:'./src/index.js',
print:'./src/print.js'
},
output:{
path:path.resolve(__dirname,'dist'),
filename:'[name].bundle.js'
},
plugins:[
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
//title: 'Output Management',
template:'./index.html'
})
],
}
现在执行 npm run dev
,再检查 /dist
文件夹。如果一切顺利,你现在应该不会再看到旧的文件,只有构建后生成的文件!
5 使用 source map
当 webpack 打包源代码时,可能会很难追踪到错误和警告在源代码中的原始位置。例如,如果将三个源文件(a.js
, b.js
和 c.js
)打包到一个 bundle(bundle.js
)中,而其中一个源文件包含一个错误,那么堆栈跟踪就会简单地指向到 bundle.js
。这并通常没有太多帮助,因为你可能需要准确地知道错误来自于哪个源文件。
为了更容易地追踪错误和警告,JavaScript 提供了 source map 功能,将编译后的代码映射回原始源代码。如果一个错误来自于 b.js
,source map 就会明确的告诉你。
source map 有很多不同的选项可用,请务必仔细阅读它们,以便可以根据需要进行配置。
对于本指南,我们使用 inline-source-map
选项,这有助于解释说明我们的目的(仅解释说明,不要用于生产环境):
添加一行代码就可以使用该功能了。devtool: 'inline-source-map',下面是出错后的提示信息,我在后面添加了中文的句号,所以报错。
6 安装webpack-dev-server
每次要编译代码时,手动运行 npm run dev
就会变得很麻烦。
webpack 中有几个不同的选项,可以帮助你在代码发生变化后自动编译代码:
- webpack's Watch Mode
- webpack-dev-server
- webpack-dev-middleware
多数场景中,你可能需要使用 webpack-dev-server
。
webpack-dev-server
为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。让我们设置以下:
npm install --save-dev webpack-dev-server
修改配置文件,告诉开发服务器(dev server),在哪里查找文件:
webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
entry:{
app:'./src/index.js',
print:'./src/print.js'
},
+ devtool: 'inline-source-map',
+ devServer:{
+ contentBase:'./dist',
+ open:true,
+ port:9000
+ },
output:{
path:path.resolve(__dirname,'dist'),
filename:'[name].bundle.js'
},
plugins:[
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
//title: 'Output Management',
template:'./index.html'
})
],
}
以上配置告知 webpack-dev-server
,在 localhost:9000
下建立服务,将 dist
目录下的文件,作为可访问文件。
让我们添加一个 script 脚本,可以直接运行开发服务器(dev server)。
package.json部分代码。代码中--config ./webpack.config.js --mode development 不是必须的,因为系统会自动去寻找congif配置文件,mode也有默认的模式。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "babel src -d release",
"dev": "webpack --config ./webpack.config.js --mode development",
+ "start":"webpack-dev-server --config ./webpack.config.js --mode development"
},
现在,我们可以在命令行中运行 npm run start
,就会看到浏览器自动加载页面。如果现在修改和保存任意源文件,web 服务器就会自动重新加载编译后的代码。
上面我们使用了CleanWebpackPlugin插件,所以运行命令后dist文件夹就会删除了,而且不会再再生成了。因为重新编译文件只在内存中。要想得到它们,我们需要关闭服务,再去执行上面的npn run dev 命令。
运行npm start 也可以,关闭服务器的快捷键是 Ctrl+c ,好像很多命令行取消服务都是这个组合键。
总结:
webpack的基本使用对比较简单。我这里只安装了四个依赖包已经一个配置文件webpack.config.js,主要用在开发环境。
- "html-webpack-plugin": "^3.2.0",
- "webpack": "^4.17.1",
- "webpack-cli": "^3.1.0",
- "webpack-dev-server": "^3.1.7"
问题:
webpack和babel如何结合在一起使用,详见下篇笔记:webpack中babel配置教程。