《一个最简单的webpack应用》

目标

建立一个lesson1项目,在项目中创建html、css、js、图片等静态文件,编写webpack配置文件,最后生成如下页面:
《一个最简单的webpack应用》 - 图1

要求:
1、使用require引入jquery,且页面中要使用jquery来操作DOM,另外html文件要引用js、css、图片文件;
2、输入命令npm run build能正确打包出静态文件,本地打开index.html时页面样式正常且无报错。

挑战

将原页面中的‘hello world’修改成‘你好 世界’、css文件打包命名为stylesheet.css,本地打开index.html时,能正确显示页面样式且无报错。

知识点

1、webpack配置文件。学习config部分常用参数含义及作用。
2、webpack loader。使用loader来解析各种静态资源文件。
3、webpack plugin。使用webpack插件来协助解析和生成资源。

课程内容

按照惯例,咱们先来个简单的 hello world 入门。
okay,新建个lesson1文件夹,进入文件夹使用 npm 安装webpack到本地

  1. mkdir lesson1 && cd lesson1
  2. npm init -y
  3. npm install webpack --save-dev
  4. # 记得在package.json文件中编写npm指令(命令指代可以查看上一节`lesson0`)

新建src文件夹,在里面编写项目静态文件

  1. mkdir src && cd src
  2. # 新建html、css、js文件
  3. touch index.html style.css main.js
  4. # npm 安装jquery
  5. npm install jquery --save
  6. # 新建img文件夹,所有图片存储在里面
  7. mkdir img

copy以下内容到index.html

  1. <html>
  2. <head>
  3. <meta charset="UTF-8" />
  4. <title>webpack-lesson1</title>
  5. </head>
  6. <body>
  7. <img src="http://static.bookstack.cn/projects/webpack2-lessons/lesson1/img/1.jpg" alt="放弃我的脸" />
  8. <h1>hello world!!!</h1>
  9. </body>
  10. </html>

copy以下内容到style.css

  1. body {
  2. text-align: center;
  3. font-size: 16px;
  4. }
  5. img {
  6. width: 500px;
  7. height: auto;
  8. }

copy以下内容到main.js

  1. var $ = require('jquery');
  2. $("body").append('<h2>This is created by jquery!</h2>');

在img文件夹里面放入一张图片,比如说1.jpg
《一个最简单的webpack应用》 - 图2

编写配置文件

新建一个 webpack.config.js配置文件和 webpack.entry.js入口文件

  1. touch webpack.config.js webpack.entry.js

copy以下代码到webpack.config.js

  1. //webpack配置文件符合commonJs模块规范
  2. var path = require('path'); //这里引入path是为了解析相对路径,配置文件某些路径要求是绝对路径
  3. module.exports = {
  4. // 入口文件,webpack据此对项目进行打包
  5. // 类型: String字符串 | Array数组 | Object对象
  6. // lesson1很简单,只使用一个入口
  7. entry: './webpack.entry.js',
  8. // webpack的入口文件,后面会创建
  9. // 定义webpack打包时的输出文件名及路径
  10. output: {
  11. // 定义webpack打包之后的文件名
  12. filename: 'webpack.bundle.js',
  13. // 定义打包文件的存储路径:当前目录的build文件夹
  14. path: path.resolve(__dirname, './build'),
  15. // 声明资源(js、css、图片等)的引用路径
  16. // webpack打包时会把html页面上的相对路径根据publicPath解析成绝对路径
  17. // eg:当publicPath为'https://jd.com/'时,如果有html或者css含有一张图片相对路径为'./img/test.jpg',打包之后html(或css)中图片的路径就会变成'https://jd.com/img/test.jpg'
  18. publicPath: ''
  19. },
  20. // 用于解析entry选项的基础目录(必须是绝对路径),该目录必须包含入口文件
  21. // 默认: process.cwd()
  22. context: __dirname
  23. };

再copy以下代码到webpack.entry.js

  1. // 入口文件在浏览器端的表现类似于html代码中的 < script >
  2. // 在这里输入 console.log('Hello world!'),能在浏览器控制台看到打印结果
  3. require('./src/index.html');
  4. require('./src/style.css');
  5. require('./src/main.js');

以上配置了webpack打包的入口文件和输出路径,以及在入口文件中引入了静态资源。但如果现在运行npm run build,命令行会报错,显示css和html文件解析错误:
《一个最简单的webpack应用》 - 图3

配置loader

出现上图错误的原因是因为咱们还没有在webpack.config.js配置相应的loader来解析html和css的文件类型

解析html文件

html-loader可以用来解析html文件并以字符串string的形式传给webpack,此外可按需对html文件做压缩。

  1. npm install html-loader --save-dev

解析css文件

css-loader能够解析css文件、并把解析后的css以字符串的形式传给style-loader,style-loader在html中通过创建< style >标签引入css

  1. npm install style-loader css-loader --save-dev

解析png和jpg图片文件

file-loader可以用来解析静态图片的引用,url-loader是对file-loader的进一步封装,它可以把较小的图片转化成base64,它的使用也依赖于file-loader。

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

安装完loaders之后,重新配置webpack.config.js
copy以下代码到webpack.config.js

  1. //webpack配置文件符合commonJs模块规范
  2. var path = require('path'); //这里引入path是为了解析相对路径,配置文件某些路径要求是绝对路径
  3. module.exports = {
  4. // 入口文件,webpack据此对项目进行打包
  5. // 类型: String字符串 | Array数组 | Object对象
  6. // lesson1很简单,只使用一个入口
  7. entry: './webpack.entry.js',
  8. // webpack的入口文件,后面会创建
  9. // 定义webpack打包时的输出文件名及路径
  10. output: {
  11. // 定义webpack打包之后的文件名
  12. filename: 'webpack.bundle.js',
  13. // 定义打包文件的存储路径:当前目录的build文件夹
  14. path: path.resolve(__dirname, './build'),
  15. // 声明资源(js、css、图片等)的引用路径
  16. // webpack打包时会把html页面上的相对路径根据publicPath解析成绝对路径
  17. // eg:当publicPath为'https://jd.com/'时,如果有html或者css含有一张图片相对路径为'./img/test.jpg',打包之后html(或css)中图片的路径就会变成'https://jd.com/img/test.jpg'
  18. publicPath: ''
  19. },
  20. // 用于解析entry选项的基础目录(必须是绝对路径),该目录必须包含入口文件
  21. // 默认: process.cwd()
  22. context: __dirname,
  23. // 定义项目里各种类型模块的处理方式
  24. module: {
  25. rules: [{
  26. test: /\.css$/,
  27. // 处理.css文件
  28. use: ['style-loader', 'css-loader']
  29. },
  30. {
  31. test: /\.(jpg|png)$/,
  32. // 处理.png和.jpg格式的图片文件
  33. use: ['url-loader?limit=10000&name=img/[name].[ext]'
  34. // limit参数指图片大小(10kb),当小于这个值时图片转为base64,当把值修改为60000时,1.jpg(50kb)会被解析成base64,打包后查看index.html代码可以看到
  35. // name参数指图片文件的命名格式,前面可以加 img/ 表示图片存储路径
  36. ]
  37. },
  38. {
  39. test: /\.html$/,
  40. // 处理.html文件
  41. use: ['html-loader']
  42. }]
  43. }
  44. };

运行npm run build命令之后,显示成功打包,build文件夹目录结构如下:
《一个最简单的webpack应用》 - 图4
会发现html和css都被打包进了webpack.bundle.js文件里面,下面是webpack.bundle.js中html部分截图:
《一个最简单的webpack应用》 - 图5

配置plugins

为了解决上面的问题,我们可以使用html-webpack-pluginextract-text-webpack-plugin来将html、css代码片段从webpack.bundle.js中抽取出来并生成相应的html(或css)文件,extract-text-webpack-plugin会自动在生成的html文件中插入<link>标签引入css

  1. npm install html-webpack-plugin extract-text-webpack-plugin --save-dev

copy以下代码到webpack.config.js

  1. //webpack配置文件符合commonJs模块规范
  2. var path = require('path'),
  3. //这里引入path是为了解析相对路径,配置文件某些路径要求是绝对路径
  4. HtmlWebpackPlugin = require('html-webpack-plugin'),
  5. //简化生成适合webpack打包的html
  6. ExtractTextPlugin = require("extract-text-webpack-plugin"); //抽取css字符串并生成css文件
  7. module.exports = {
  8. // 入口文件,webpack据此对项目进行打包
  9. // 类型: String字符串 | Array数组 | Object对象
  10. // lesson1很简单,只使用一个入口
  11. entry: './webpack.entry.js',
  12. // webpack的入口文件,后面会创建
  13. // 定义webpack打包时的输出文件名及路径
  14. output: {
  15. // 定义webpack打包之后的文件名
  16. filename: 'webpack.bundle.js',
  17. // 定义打包文件的存储路径:当前目录的build文件夹
  18. path: path.resolve(__dirname, './build'),
  19. // 声明资源(js、css、图片等)的引用路径
  20. // webpack打包时会把html页面上的相对路径根据publicPath解析成绝对路径
  21. // eg:当publicPath为'https://jd.com/'时,如果有html或者css含有一张图片相对路径为'./img/test.jpg',打包之后html(或css)中图片的路径就会变成'https://jd.com/img/test.jpg'
  22. publicPath: ''
  23. },
  24. // 用于解析entry选项的基础目录(必须是绝对路径),该目录必须包含入口文件
  25. // 默认: process.cwd()
  26. context: __dirname,
  27. // 定义项目里各种类型模块的处理方式
  28. module: {
  29. rules: [{
  30. test: /\.css$/,
  31. // 处理.css文件
  32. use: ExtractTextPlugin.extract({
  33. fallback: "style-loader",
  34. use: "css-loader"
  35. })
  36. },
  37. {
  38. test: /\.(jpg|png)$/,
  39. // 处理.png和.jpg格式的图片文件
  40. use: ['url-loader?limit=10000&name=img/[name].[ext]'
  41. // limit参数指图片大小(10kb),当小于这个值时图片转为base64,当把值修改为60000时,1.jpg(50kb)会被解析成base64,打包后查看index.html代码可以看到
  42. // name参数指图片文件的命名格式,前面可以加 img/ 表示图片存储路径
  43. ]
  44. },
  45. {
  46. test: /\.html$/,
  47. // 处理.html文件
  48. use: ['html-loader']
  49. }]
  50. },
  51. // webpack插件
  52. plugins: [
  53. // 生成html文件
  54. new HtmlWebpackPlugin({
  55. template: './src/index.html',
  56. filename: 'index.html'
  57. }),
  58. // 生成css文件,一下括号中的'style.css' 是打包后的css文件名,可自定义
  59. new ExtractTextPlugin("style.css")
  60. ]
  61. };

由于已经使用 html-webpack-plugin 以 index.html 为模版生成了html文件,webpack打包时会引入 index.html ,所以在webpack.entry.js中就没必要再次 require('index.html') ,修改完的webpack.entry.js如下:

  1. // 入口文件在浏览器端的表现类似于html代码中的 < script >
  2. // 在这里输入 console.log('Hello world!'),能在浏览器控制台看到打印结果
  3. // require('./src/index.html');
  4. require('./src/style.css');
  5. require('./src/main.js');

运行npm run build命令,显示打包成功,build目录结构如下:
《一个最简单的webpack应用》 - 图6
成功生成独立的html和css文件,本地打开index.html,页面显示一切正常且无报错。
《一个最简单的webpack应用》 - 图7棒棒哒~~~

补充知识

1、entry属性:根据你的项目情况,如果是SPA(single page app 单页面应用),使用字符串即一个入口即可;如果是MPA(multiple page app),建议使用Object类型,每一个属性都是一个入口,入口名称是属性的名称,入口文件是属性的值
2、extract-text-webpack-plugin可以自定义css文件名,也可以拆分成几个css文件,详情可看官方文档