step 1 创建项目目录结构

vue-todo
├─dist
    │  index.html
└─src
    │  entry.js : 入口文件。负责引入(将被webpack处理的)页面的所有资源(js/图片/css)。
    │  
    ├─css
    ├─images
    └─js

step 2 初始化环境

使用命令行工具在项目根目录(此处为vue-todo)下输入npm init -y并回车,初始化npm环境。
npm使用前置条件

初始化webpack环境
npm i wepack webpack-cli

step 3 为使用Webpack做准备

在项目根目录下新建webpack.config.js文件,这个文件是用来配置webpack的运行参数的。
为文件添加如下内容:

const path = require('path'); //路径管理模块,使用它可以高效获取项目路径,避免路径错误.

/**
 * 在这个对象中配置webpack的运行参数
 */
var config = {
    //指定环境
    mode: "development", //当前在开发产品
    //指定集成引入资源的入口js文件
    entry: path.join(__dirname,"./src/entry.js"),
    //webpack处理后输出的文件的配置
    output:{
        path: path.join(__dirname,"./dist"),//指定输出的目录
        filename: 'bundle.js',//输出的文件的文件名
    }
}

/**
 * 向外暴露配置webpack的对象
 */
module.exports = config;

之后再打开package.json,找到该json中'scripts'属性,在未修改前应该如下所示:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
  },

为其添加webpack相关配置后应该多出如下所示的一行(build):

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config webpack.config.js"
  },

之后在命令行工具中,在项目根目录下运行npm rum build,应该得到类似如下的成功信息:

> webpack --config webpack.config.js

Hash: a5b152d4afb92392b2f6
Version: webpack 4.39.1
Time: 419ms
Built at: 2019-08-10 11:38:12 PM
    Asset       Size  Chunks             Chunk Names
bundle.js  930 bytes       0  [emitted]  main
Entrypoint main = bundle.js
[0] ./src/entry.js 0 bytes {0} [built]

step 4 为webpack添加常用的loader以处理css,图片等资源

在项目根目录的css文件夹下新建index.css文件

html, body{
    padding: 0;
    margin: 0;
}

entry.js中对改文件进行引用

import './css/index.css'

此时运行npm run build会报错,信息如下(省略了部分内容):

ERROR in ./src/css/index.css 1:10
Module parse failed: Unexpected token (1:10)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> html, body{
|     padding: 0;
|     margin: 0;
 @ ./src/entry.js 1:0-24

可以看到错误发生在css文件,并且错误提示说:“你可能需要一个合适的Loader来处理这种文件类型,当前没有loader被配置用来处理这一文件,详情可查阅 https://webpack.js.org/concep... ”。
跳转到提示网址,经过阅读后发现这虽然是一篇不错的指南,但是对于我们现在遭遇的问题帮助不大。
我们仍然寄希望于官方对此给出了解决方案,因此我们截取文档的域名:webpack.js.org,然后发起谷歌搜索,搜索关键词如下
css site:webpack.js.org
我搜索得到的结果如下
图片描述
首先打开css-loader,我们会认为这应该能解决我们的问题了。但开门见山的对css=loader的描述并不符合哦我们的预期:

The css-loader interprets @import and url() like import/require() and will resolve them.
意思是:css-loader可以处理@import和url()的使用并解析它们。

这与我们遇到的错误关系不大。所以继续查看搜索结果的第二个文档,即style-loader。
开门见山的描述如下:

Inject CSS into the DOM.
将CSS注入到DOM中

将CSS注入到DOM中,那么必然可以处理CSS,显然这个是我们想要的。
继续阅读并按照文档要求进行配置。
安装loader:npm i style-loader css-loader
webpack.config.js中配置module属性,结束后我们的文件应该如下所示

const path = require('path'); //路径管理模块,使用它可以高效获取项目路径,避免路径错误.

/**
 * 在这个对象中配置webpack的运行参数
 */
var config = {
    //指定集成引入资源的入口js文件
    entry: path.join(__dirname,"./src/entry.js"),
    //webpack处理后输出的文件的配置
    output:{
        path: path.join(__dirname,"./dist"),//指定输出的目录
        filename: 'bundle.js',//输出的文件的文件名
    },
    module: {
        rules: [
          {
            test: /\.css$/, //正则表达式的语法
            use: ['style-loader', 'css-loader'], //符合正则表达式的文件被loader处理的顺序是从use列表中从右往左的
          },
        ],
    }
}

/**
 * 向外暴露配置webpack的对象
 */
module.exports = config;

保存后再次运行npm run build,没有再报错。
同理同法,为图片资源,字体资源添加loader,具体过程不再展示,完成后webpack.config.js应该如下所示(不要忘记安装用到的loader):

const path = require("path"); //路径管理模块,使用它可以高效获取项目路径,避免路径错误.

/**
 * 在这个对象中配置webpack的运行参数
 */
var config = {
  //指定集成引入资源的入口js文件
  entry: path.join(__dirname, "./src/entry.js"),
  //webpack处理后输出的文件的配置
  output: {
    path: path.join(__dirname, "./dist"), //指定输出的目录
    filename: "bundle.js" //输出的文件的文件名
  },
  module: {
    rules: [
      { test: /\.css$/, use: ["style-loader", "css-loader"] },
      { test: /\.(jpg|jpeg|png|gif)$/, use: "url-loader" },
      { test: /\.(woff|woff2|ttf|eot|svg)$/, use: "url-loader" }
    ]
  }
};

/**
 * 向外暴露配置webpack的对象
 */
module.exports = config;

此时在index.html中引入入口js即 <script src="./bundle.js" type="text/javascript">
由于在index.css中有如下设置

html, body{
    padding: 0;
    margin: 0;
    background-color: cyan;
}

此时直接打开index.html文件(用的是file://协议)会看到页面背景色为青蓝色。
至此,基本的webpack环境的搭建已经完成,之后的所有步骤都是使webpack的使用更加方便罢了。


step 5 引入webpack-dev-server

webpack dev server官方文档

先安装webpack-dev-server:npm i webpack-dev-server
安装后打开npm在当前项目中的配置文件package.json配置运行项目中的webpack-dev-server的脚本。经过配置后package.json的scripts属性应当如下:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config webpack.config.js",
    "dev": "webpack-dev-server"
  },

尝试运行npm run dev
命令行工具没有报错信息,此时通过浏览器访问localhost:8080,如果打开一个非常白板的网页(如下图所示)则说明配置基本成功。
成功运行webpack-dev-server
点击页面上的dist,会自动打开dist下的index.html,同时页面背景为青蓝色,表明css引入成功。



打开webpack.config.js对webpack-dev-server的常用运行参数进行一些配置。配置结束后webpack.config.js应当如下:
const path = require("path"); //路径管理模块,使用它可以高效获取项目路径,避免路径错误.

/**
 * 在这个对象中配置webpack的运行参数
 */
var config = {
  //指定集成引入资源的入口js文件
  entry: path.join(__dirname, "./src/entry.js"),
  //webpack处理后输出的文件的配置
  output: {
    path: path.join(__dirname, "./dist"), //指定输出的目录
    filename: "bundle.js" //输出的文件的文件名
  },
  module: {
    rules: [
      { test: /\.css$/, use: ["style-loader", "css-loader"] },
      { test: /\.(jpg|jpeg|png|gif)$/, use: "url-loader" },
      { test: /\.(woff|woff2|ttf|eot|svg)$/, use: "url-loader" }
    ]
  },
  //配置webpack-dev-server的运行参数
  devServer: {
    open: true, //运行后自动打开浏览器
    port: 3000, //启动的服务器的监听端口
    contentBase: path.join(__dirname, "./dist"), //指定托管的网站文件的根目录
  }
};

/**
 * 向外暴露配置webpack的对象
 */
module.exports = config;

再运行npm run dev后应当能自动打开网页并且网页的地址为:localhost:3000

并且在命令行工具中应当能看到如下提示(省略了很多无关部分):

i 「wds」: Project is running at http://localhost:3000/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from 

请注意这里的第二行和第三行,其意思分别是:(一)经过webpack处理后的输出可以通过/路径获取,(二)未经过webpack处理的内容仍然在D:\HTML\vuejs\projects\vue-todo目录下。
这什么意思?不妨在浏览器中输入http://localhost:3000/bundle.js,预期结果是我们能正常打开一个文件(由于经过webpack处理,所以文件内容基本看不懂是正常的)。这便是经过webpack处理后的输出(即bundle.js)可以通过/(即http://localhost:3000/)来访问。
而不未经过webpack处理的(比如./src/index.html)并不能通过http://localhost:3000/index.html访问。
所以将index.html中的`<script src="./bundle.js"></script>改为<script src="/bundle.js"></script>

另外可以发现在http://localhost:3000/对应的实际文件夹中并没有bundle.js,这是因为 webpack-dev-sever 将其保存在内存中,这使得热更新更快更高效,这也是这里建议更换script标签的src源的原因。

step 6 引入html-webpack-plugin

介绍:上一步提到,将bundle.js保存在内存中,从而使更新更快更高效。在这一步中引入 html-webpack-plugin 插件,可以对 html文件 做同样的操作。并且该插件会自动添加script标签来引入webpack处理后的js文件。

先安装该插件:npm i html-webpack-plugin

之后在webpack的配置文件webpack.config.js中进行相关配置
首先引入该模块:var htmlWebpackPlugin = require("html-webpack-plugin");
其次在plugins属性中new出该组件:

  //用来引入webpack的插件
  plugins: [
    //引入html-webpack-plugin插件
    new htmlWebpackPlugin({
      //指定要被插件处理的页面
      template: path.join(__dirname, "./dist/index.html"),
      //指定页面处理后的名字
      filename: "index.html"
    })
  ]

到此便配置完成

再次运行npm run div,在自动弹出的网站首页中检查源代码,应当能够在文档几乎结束,贴着</body>标签附近发现<script type="text/javascript" src="bundle.js"></script>,这意味着插件引用成功。并且以为这我们可以删去自己写的引入bundle.js的script标签。

step 7 启用热更新

从第六步第七步我们可以知道,现在网页和入口js文件均在内存中,有极高的热更新效率。因此我们开启web-dev-server提供的热更新功能——不需要手动刷新,网页会自动监测js文件的变更刷新自己。

webpack.config.js中的devServer属性中添加hot:true的键值对,表明开启热更新。
编辑后的文件应该如下:

devServer: {
    open: true, //运行后自动打开浏览器
    port: 3000, //启动的服务器的监听端口
    contentBase: path.join(__dirname, "./dist"), //指定托管的网站文件的根目录
    hot: true //启用热更新
  },

如此还不够,热更新需要插件 HotModuleReplacementPlugin 支持,这个插件不需要我们独立安装,但仍然需要在plugins属性中 new 出来,为此要先引入Webpack模块。
const webpack = require('webpack');
之后再在plugins中添加new webpack.HotModuleReplacementPlugin(),添加完毕后plugins属性应当如下:

  plugins: [
    //引入html-webpack-plugin插件 这里的htmlWebpackPlugin是第四行require进来的
    new htmlWebpackPlugin({
      //指定要被插件处理的页面
      template: path.join(__dirname, "./dist/index.html"),
      //指定页面处理后的名字
      filename: "index.html"
    }),
    new webpack.HotModuleReplacementPlugin()
  ]

再次运行npm run dev,若无报错,基本上配置成功了。然后进入index.css文件修改background-color样式,回到浏览器会发现并未手动点击刷新但背景颜色已经如愿改变。

这就是本文的全部内容了,欢迎交流讨论。


阳光号
129 声望5 粉丝