账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    webpack如何实现热替换
    32
    0

    参照vue-cli建立的项目中有关开发模式的webpack配置,基本的代码和其配置基本一样,但是vue的可以实现热替换,就是内容改了后不用刷新页面内容也会改变,而我写的配置只能实现热重载,也就是更改内容后自动刷新,下面是配置
    webpack.base.conf.js

    var path = require('path');
    var config = require('../config');
    var webpack = require('webpack');
    var utils = require('./utils');
    function resolve(dir) {
      return path.join(__dirname, '..', dir);
    }
    module.exports = {
      entry: {
        app: './src/main.js'
      },
      output: {
        path: config.build.assetsRoot,
        filename: '[name].js',
        publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath
      },
      resolve: {
        extensions: ['.js', '.json'],
        alias: {
          'components': path.join(__dirname, '../src/components'),
          'common': path.join(__dirname, '../src/comon')
        }
      },
      module: {
        rules: [{
          test: /\.js$/,
          loader: 'eslint-loader',
          enforce: 'pre',
          include: resolve('src'),
          options: {
            formatter: require("eslint-friendly-formatter")
          }
        }, {
          test: /\.js$/,
          loader: 'babel-loader',
          include: resolve('src'),
          options: {
            presets: ['env'],
            plugins: ['transform-runtime'],
            cacheDirectory: true
          }
        }, {
          test: /\.ejs$/,
          loader: 'ejs-loader',
        }, {
          test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
          loader: 'url-loader',
          options: {
            limit: 10000,
            name: utils.assetsPath('images/[name].[hash:7].[ext]')
          }
        }, {
          test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
          loader: 'url-loader',
          options: {
            limit: 10000,
            name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
          }
        }]
      },
      externals: {
        jquery: 'jQuery'
      }
    }

    webpack.dev.conf.js

    var webpack = require('webpack');
    var baseWebpackConfig = require('./webpack.base.conf');
    var config = require('../config');
    var merge = require('webpack-merge');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
    Object.keys(baseWebpackConfig.entry).forEach(function (name) {
      baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]);
    })
    module.exports = merge(baseWebpackConfig, {
      module: {
        rules: [{
          test: /\.scss$/,
          use: [{
            loader: 'style-loader'
          }, {
            loader: 'css-loader',
            options: {
              minimize:true,
              sourceMap: config.dev.cssSourceMap
            }
          }, {
            loader: 'postcss-loader',
            options: {
              sourceMap: config.dev.cssSourceMap,
              plugins: function () {
                return [
                  require('autoprefixer')()
                ];
              }
            }
          }, {
            loader: 'sass-loader',
            options: {
              sourceMap: config.dev.cssSourceMap
            }
          }],
        }]
      },
      devtool: '#cheap-module-eval-source-map',
      plugins: [
        new webpack.DefinePlugin({
          'process.env': JSON.stringify(config.dev.env.NODE_ENV)
        }),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoEmitOnErrorsPlugin(),
        new HtmlWebpackPlugin({
          filename: 'index.html',
          template: 'index.html',
          inject: true
        }),
        new FriendlyErrorsPlugin()
      ]
    })

    dev-client.js

    require('eventsource-polyfill')
    var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
    hotClient.subscribe(function (event) {
      if (event.action === 'reload') {
        window.location.reload()
      }
    })

    dev-server.js

    var config = require('../config');
    process.env.NODE_ENV = config.dev.env.NODE_ENV;
    var opn = require('opn');
    var path = require('path');
    var express = require('express');
    var webpack = require('webpack');
    var proxyMiddleware = require('http-proxy-middleware');
    var webpackConfig = require('./webpack.dev.conf');
    var port = process.env.port || config.dev.port;
    var autoOpenBrowser = !!config.dev.autoOpenBrowser;
    var proxyTable = config.dev.proxyTable;
    var app = express();
    var compiler = webpack(webpackConfig);
    var devMiddleware = require('webpack-dev-middleware')(compiler, {
      publicPath: webpackConfig.output.publicPath,
      quiet: true,
      // stats: {
      //   color: true
      // }
    });
    var hotMiddleware = require('webpack-hot-middleware')(compiler, {
      log: () => {}
    });
    // force page reload when html-webpack-plugin template changes
    compiler.plugin('compilation', function (compilation) {
      compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
        hotMiddleware.publish({
          action: 'reload'
        });
        cb();
      })
    })
    Object.keys(proxyTable).forEach(function (content) {
      var options = proxyTable[content];
      if (typeof options === 'string') {
        options = {
          target: options
        }
      }
      app.use(proxyMiddleware(options.filter || content, options))
    })
    app.use(require('connect-history-api-fallback')());
    app.use(devMiddleware);
    app.use(hotMiddleware);
    // serve pure static assets
    var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
    app.use(staticPath, express.static('./static'))
    var uri = 'http://localhost:' + port;
    var _resolve;
    var readyPromise = new Promise(resolve => {
      _resolve = resolve
    });
    console.log('> Starting dev server...')
    devMiddleware.waitUntilValid(function () {
      console.log('> Listening at ' + uri + '\n');
      if (autoOpenBrowser) {
        opn(uri);
      }
      _resolve();
    })
    var server = app.listen(port);
    module.exports = {
      ready: readyPromise,
      close: () => {
        server.close()
      }
    }

    其中HotModuleReplacementPlugin这个插件就是用来配置热替换的,这个我也配置上去了,但是还是不行,不知道是不是还漏了什么步骤,和vue项目的配置主要区别就是少了针对vue文件处理,其他内容基本都是一样的,不知道问题是否出现在这个上?

    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 10 元积分
        全部回答
    • 0
    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部