注:在github上看到一篇比较好的webpack入门教程,本人也是为了加深印象以此记录。奉上原文地址:https://github.com/kingvid-ch

《使用webpack-dev-server实现热更新》

目标

建立lesson02项目,内容和上节lesson01一致,当用浏览器访问http://localhost:8080/index.html时,修改任一html、css、js、图片文件,页面都会自动刷新。

挑战

在原项目的基础上,将‘hello world’修改成‘你好 世界’、字体颜色修改成#ccc、并在2秒之后渐隐,浏览器页面http://localhost:8080/index.html会自动刷新,能正确显示页面样式且无报错。

课程内容

webpack-dev-server很棒的一点是当修改页面的时候不会整页刷新,而是会热更新,当页面模块体积较大时可以省下很多时间。
首先安装npm包

npm install webpack-dev-server -save-dev
编写配置文件

copy以下代码到webpack.config.js:

var path = require('path'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
ExtractTextPlugin = require("extract-text-webpack-plugin"),
webpack = require('webpack'); //这里引入webpack是为了使用webpack的热更新功能以及其他自带插件,见 module.exports.plugins
module.exports = {
  entry: [
    // 给webpack-dev-server启动一个本地服务,并连接到8080端口
    'webpack-dev-server/client?http://localhost:8080',

    // 给上面启动的本地服务开启自动刷新功能,'only-dev-server'的'only-'意思是只有当模块允许被热更新之后才有热加载,否则就是整页刷新
    'webpack/hot/only-dev-server',

    // webpack的入口文件,注意这个声明必须写在上面两个后面,webpack-dev-server才有效
    './webpack.entry.js'
  ],
  output: {
    filename: 'webpack.bundle.js',
    path: path.resolve(__dirname, './build'),
    publicPath: ''
  },
  context: __dirname,
  module: {
    rules: [{
      test: /\.css$/,
      use: ExtractTextPlugin.extract({
        fallback: "style-loader",
        use: "css-loader"
      })
    },
    {
      test: /\.(jpg|png)$/,
      use: ['url-loader?limit=10000&name=img/[name].[ext]']
    },
    {
      test: /\.html$/,
      use: ['html-loader']
    }]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html'
    }), 
    new ExtractTextPlugin("style.css"),
    // 开启webpack全局热更新
    new webpack.HotModuleReplacementPlugin(),

    // 当接收到热更新信号时,在浏览器console控制台打印更多可读性高的模块名称等信息
    new webpack.NamedModulesPlugin()
  ],

  // 定义webpack-dev-server
  devServer: {
    contentBase: path.resolve(__dirname, 'src'),
    // 静态文件目录位置,只有当你需要在webpack-dev-server本地服务器查看或引用静态文件时用到。类型:boolean | string | array, 建议使用绝对路径
    hot: true,
    // 模块热更新。依赖于HotModuleReplacementPlugin
    noInfo: false,
    // 在命令行窗口显示打包信息
  }
};

看到上面修改得地方有:

1. require('webpack')
2. 修改entry属性,插入两个webpack-dev-server入口
3. 在plugin属性增添了webpack自带得HotModuleReplacementPlugin,NamedModulesPlugin两个插件
4. 声明devServer属性

还需要在package.json文件中得script字段增加:

 "scripts": {
    "start": "node_modules/.bin/webpack-dev-server",
    "build": "node_modules/.bin/webpack"
  },

最后,运行npm run start命令。在浏览器中打开http://localhost:8080/index.html,发现页面显示正常,然后修改style.css文件,发现控制台中会有更新,但是页面并没有自动刷新。(这是因为extract-text-webpack-plugin不支持热更新)为了解决问题,我们不使用extract-text-webpack-plugin,然后运行代码,可以看到浏览器页面能够自动刷新了。

注意:webpack会对require的文件保持监听,因为index.html并没有被require,所以修改index.html得时候不会刷新页面,此时在main.js文件中require一下index.html就会是实现热更新。

devtool

当页面某个部分样式要调整时,由于不知道对应样式的具体位置,会增加修改的时间成本。webpack有个属性能把样式都索引到对应的css文件里面,这个属性就是 devtool,特别当页面很复杂,多个模块引入多个css文件时,devtool能大大提高咱们的调试效率。

1、配置了devtool属性
2、在module属性 --> rules --> css-loader 添加了sourceMap参数

var path = require('path'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
webpack = require('webpack'); //这里引入webpack是为了使用webpack的热更新功能以及其他自带插件,见 module.exports.plugins
module.exports = {
  entry: [
    // 给webpack-dev-server启动一个本地服务,并连接到8080端口
    'webpack-dev-server/client?http://localhost:8080',

    // 给上面启动的本地服务开启自动刷新功能,'only-dev-server'的'only-'意思是只有当模块允许被热更新之后才有热加载,否则就是整页刷新
    'webpack/hot/only-dev-server',

    // webpack的入口文件,注意这个声明必须写在上面两个后面,webpack-dev-server才有效
    './webpack.entry.js'
  ],
  output: {
    filename: 'webpack.bundle.js',
    path: path.resolve(__dirname, './build'),
    publicPath: ''
  },
  context: __dirname,
  module: {
    rules: [{
      test: /\.css$/,
      use: ['style-loader', 'css-loader?sourceMap' // 这里需要配置sourceMap参数
      ]
    },
    {
      test: /\.(jpg|png)$/,
      use: ['url-loader?limit=10000&name=img/[name].[ext]']
    },
    {
      test: /\.html$/,
      use: ['html-loader']
    }]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html'
    }),
    // 开启webpack全局热更新
    new webpack.HotModuleReplacementPlugin(),

    // 当接收到热更新信号时,在浏览器console控制台打印更多可读性高的模块名称等信息
    new webpack.NamedModulesPlugin()
  ],

  // 定义webpack-dev-server
  devServer: {
    contentBase: path.resolve(__dirname, 'src'),
    // 静态文件目录位置,只有当你需要在webpack-dev-server本地服务器查看或引用静态文件时用到。类型:boolean | string | array, 建议使用绝对路径
    hot: true,
    // 模块热更新。依赖于HotModuleReplacementPlugin
    noInfo: false,
    // 在命令行窗口显示打包信息
  },

  // 开启devtool:开发阶段特别有用,比如说用sass开发,在浏览器查看样式时可以方便知道该样式是映射到sass具体的第几行
  devtool: 'source-map'
};

fsrookie
2.9k 声望256 粉丝

目前很多文章都是摘抄记录其他教程。见谅。