openks / openks.github.io

openks的demo页
http://openks.github.io
0 stars 0 forks source link

webpack的HMR(Hot Module Replacement)模块热替换 #2

Open openks opened 7 years ago

openks commented 7 years ago

公司新来同事做新项目,我想看下他技术怎样就让他部署了个vue项目
完了之后在编写代码的时候发现改动之后要等待N秒才有反应查看了下项目配置发现没有加入模块热替换, 由于之前一直使用cli工具已经配好了的能感觉到文件改动后响应速度的明显区别我决定对他项目进行修改加入模块热替换

openks commented 7 years ago

文件结构如下:

.
├── index.html
├── node_modules
├── package.json
├── src
│   ├── App.vue
│   ├── assets
│   ├── components
│   ├── main.js
│   ├── md
│   ├── router
│   ├── routes
│   ├── style
│   ├── utils
│   └── views
└── webpack.config.js

index.html 公共页里引入样式文件及css文件 我感觉应该不是这么玩的

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
        <title></title>
        <link rel="stylesheet" href="src/assets/mui/mui.min.css"/>
    </head>
    <body>
        <div id="app"></div>
    </body>
    <script src="src/assets/zepto/zepto.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="src/assets/mui/mui.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="bundle.js" type="text/javascript" charset="utf-8"></script>
</html>

package.json scripts如下

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

webpack.config.js文件如下

module.exports = {
    entry:"./src/main.js",//入口文件
    output:{ //输出目录及文件
        path:__dirname,
        filename:"bundle.js"
    },
    devtool:"source-map",//调试工具
    module:{
        loaders:[
            {
                test:/\.vue$/,
                loader:"vue-loader"
            },
            //如果项目中没有使用es6,不需要加载这个loader
            {
                test:/\.js$/,
                loader:"babel-loader",
                query: {
                    presets: ['es2015']
                }
            },
            {
                test:/\.scss$/,
                loader:"style-loader!css-loader!sass-loader"
            },
            //css文件中有背景图片----把图片地址转换为base64地址
            {
                test:/\.(jpg|png|gif)$/,
                loader:"url-loader?limit=102400"
            },
            //字体文件
            {
                test:/\.(eot|woff|svg|ttf|woff2|gif|appcache)(\?|$)/,
                loader:'file-loader?name=[name].[ext]'
            }
        ]
    },
    resolve: {
        alias: {
           'vue$': 'vue/dist/vue.esm.js'
        }
    }
}

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}
openks commented 7 years ago

同事只用了webpack-dev-server而且没有做任何处理,怪不得感觉编译很慢,每次都全部编译不慢才怪

openks commented 7 years ago

根据webpack的文档 development ,DevServerHMR 进行配置
配置完就遇到了第一个问题: vue.esm.js:479 [Vue warn]: Cannot find element: #app 明明index.html文件里有#app节点却报找不到奇了怪了,仔细查看配置文件发现了一个HtmlWebpackPlugin是不是跟这个东西有关系,看了下这个包的说明 发现里面有个

// Generates default index.html

说明重新生成一个新的html文件但是也有配置可以只用存在模板 在对比用cli工具生成的配置文件里的配置

    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html', //使用我们自己的index.html文件
      inject: true //自动注入
    }),
openks commented 7 years ago

index.html 如果不注掉文件会出现文件找不到情况

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>ttt</title>
<!-- <link rel="stylesheet" href="./src/assets/mui/mui.min.css"/> -->
    </head>
    <body>
        <div id="app"></div>
    </body>
<!--    <script src="./src/assets/zepto/zepto.min.js" type="text/javascript" charset="utf-8"></script>
<script src="./src/assets/mui/mui.min.js" type="text/javascript" charset="utf-8"></script> -->
</html>

webapck.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    entry: {
        app: './src/main.js',
    },
    devtool:"inline-source-map",//调试工具
    devServer:{
        contentBase: path.join(__dirname, "dist"),
            compress: true,
            port: 9000,
         hot: true
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: true
        }),
        new webpack.HotModuleReplacementPlugin()
    ],
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module:{
        loaders:[
            {
                test:/\.vue$/,
                loader:"vue-loader"
            },
            //如果项目中没有使用es6,不需要加载这个loader
            {
                test:/\.js$/,
                loader:"babel-loader",
                query: {
                    presets: ['es2015']
                }
            },
            {
                test:/\.scss$/,
                loader:"style-loader!css-loader!sass-loader"
            },
            //css文件中有背景图片----把图片地址转换为base64地址
            {
                test:/\.(jpg|png|gif)$/,
                loader:"url-loader?limit=102400"
            },
            //字体文件
            {
                test:/\.(eot|woff|svg|ttf|woff2|gif|appcache)(\?|$)/,
                loader:'file-loader?name=[name].[ext]'
            }
        ]
    },
    resolve: {
        alias: {//别名配置,将后缀名为vue的执行
           'vue$': 'vue/dist/vue.esm.js'
        }
  }
}

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}
openks commented 7 years ago

接下来要处理的是如下内容