webpack使用总结 - ES六、模块热替换

接着上一篇文章中的配置css

一. Webpack Dev Server

在实际的开发中,不会每次改下代码,而后再手动的打包、手动刷新页面,这样太麻烦了,webpack也是支持自动打包及刷新页面的。html

webpack-dev-server能够自动的打开页面、自动的打包、自动的刷新、因此在项目中通常采起这种方式。node

安装:yarn add webpack-dev-serverwebpack

在package.json中增长:git

"scripts": {
    "build": "webpack",
+ "dev": "webpack-dev-server"
}
复制代码

webpack.config.js中添加:es6

module.exports = {
+ devServer: {
+ open: true // 自动打开页面
+ }
}
复制代码

页面就是在本地的服务中打开,注意使用webpack-dev-server不会生成打包后的目录,它将文件都放在内存中。github

还有一个比较经常使用的配置proxy,proxy能够将你的请求进行代理,避免出现跨域问题。web

举个例子:ajax

ajax.jsjson

const ajax = () => {
  const xhr = new XMLHttpRequest()
  const url = '/api/wikisecond/lemmasecond?lemmaId=10629668'
  xhr.open('get', url)
  xhr.onreadystatechange = function () {
    if(xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 304)) {
      console.log(JSON.parse(xhr.responseText))
    }
  }
  xhr.send()
}

export default ajax
复制代码

index.js

+ import ajax from './ajax'
+ ajax()
复制代码

webpack.config.js

devServer: {
    open: true,
    proxy: {
        '/api': {
            target: 'https://baike.baidu.com',
            changeOrigin: true,
            secure: false,
        }
    }
}
复制代码

上面配置的意思就是将http://localhost:8080/api/xxxx代理到https://baike.baidu.com/api/xxx

从新打包结果:

直接拿到了百度百科的接口返回内容,没有出现跨域。

二. 模块热替换

模块热替换的意思就是在不从新刷新页面的状况下,替换模块,举个例子:

addItem.js

import style from './style/index.scss'

export default function () {
  const button = document.createElement('button')
  button.textContent = 'add Item'
  button.onclick = () => {
    const item = document.createElement('p')
    item.textContent = 'item'
    item.classList.add(style.item)
    document.body.appendChild(item)
  }
  document.body.appendChild(button)
}
复制代码

index.js

+ import addItem from './addItem'
+ addItem()
复制代码

index.scss

.item {
  &:nth-of-type(odd) {
    background: pink;
  }
}
复制代码

因为以前配置了css-loader的modules致使css名很难辨认,这里优化一下:

{
   loader: 'css-loader',
   options: {
       importLoaders: 2,
- modules: true
+ modules: {
+ localIdentName: '[name]_[local]_[hash:base64]'
+ }
   }
}
复制代码

打包后:

每点击一下add Item按钮就会在页面上增长一个item元素,奇数元素的背景色为粉色。

若是这时候改一下背景色:

index.scss

.item {
   &:nth-of-type(odd) {
- background: pink;
+ background: orange;
   }
 }
复制代码

页面会从新刷新,那么以前添加的item就都没了。

又得去点击add Item按钮才行,若是想保持以前的页面状态,那么就要用到模块热替换功能:

wenpack.config.js

+ const webpack = require('webpack')

devServer: {
    open: true,
    proxy: {
      '/api': {
        target: 'https://baike.baidu.com',
        changeOrigin: true,
        secure: false,
      }
    },
+ hot: true,
+ hotOnly: true
},
plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve('template', 'index.html')
    }),
    new CleanWebpackPlugin(),
+ new webpack.HotModuleReplacementPlugin()
]
复制代码

hot就是开启模块热替换,hotOnly是告诉webpack在模块热替换失败的时候不要从新刷新页面。

可是关于js代码的热更新就有点麻烦,得这样写:

index.js

if (module.hot) {
    module.hot.accept('变更的模块路径', function () {
      // 作一些事情
    })
}
复制代码

三. 处理ES6语法

虽然ES6在很早就发布了,可是仍是有浏览器没有实现ES6中的部分语法,因此须要对ES6的语法进行降级,要用到的就是babel了。

找到官方推荐配置,webpack

  1. 安装相关包

    yarn add babel-loader @babel/core @babel/preset-env -D
    复制代码
  2. webpack.config.js中添加

    module: {
        rules: [
    + { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }
        ]
    }
    复制代码
  3. 建立.babelrc文件:

    {
        "presets": ["@babel/preset-env"]
    }
    复制代码
  4. 测试一下:

    es6-test.js

    export default async () => {
        await new Promise(resolve => {
            setTimeout(() => {
                console.log('step 1')
                resolve()
            }, 1000)
        })
        console.log('step 2')
    }
    复制代码

    index.js

    import es6Test from './es6-test'
    es6Test()
    复制代码

    打包后:

    为什么按照官网的配置也会出错!!!

    搜索了一下,发现了新世界,babel竟然也这么难配置?看了不少教程,我以为这个写的最好Babel快速上手使用指南,那么就按照这篇来配置:

    yarn add @babel/plugin-transform-runtime -D

    yarn add @babel/runtime core-js@3

    .babelrc

    {
         "presets": [
             ["@babel/preset-env", {
                 "modules": false,
                 "useBuiltIns": "usage",
                 "corejs": 3
             }]
         ],
         "plugins": ["@babel/plugin-transform-runtime"]
     }
    复制代码

    从新打包,终于能够了。

    开发模式打包的大小:

    正式模式打包的大小:

完整的配置:GitHub

相关文章
相关标签/搜索