webpack基础用法代码实践

136 阅读3分钟

默认是webpack4

难度:🌟🌟 🌟

实践

源代码

webpack-base master分支

包含内容

解析es6+,jsx;

.babelrc
{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
    ]
}
webpack配置
 module: {
        rules: [
            {
                test: /.js$/,
                use: 'babel-loader'
            },
         }
  }

解析css less;

module: {
        rules: [
            {
                test: /.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /.less$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ]
            }
        ]
 }

解析图片字体;

// file-loader 可以处理图片和字体;
// url-loader 也可以,url-loader还可以设置较小资源自动base64
{
        test: /.(png|jpg|gif|jpeg)$/,
        use: [
            {
                loader: 'url-loader', 
                options: {
                    limit: 10240
                }
            }
        ]
 },
{
    test: /.(woff|woff2|eot|ttf|otf)$/,
    use: 'file-loader'
}

webpack文件监听;

  • 文件监听原理分析 轮询判断文件的最后编辑时间是否变化; 某个文件发生了变化,并不会立刻告诉监听者,而是先缓存起来,等aggregateTimeout的时间后, 再一起更新;
module.exports = {
    watch:true,
    watchOptions: {
        ignored: /node_modules/,
        aggregateTimeout: 300,
         poll: 1000 // 每秒检查一次变动
    }
}

wepack热更新及其原理;

  • 原理
  • webpack-dev-server(WDS)的功能提供 bundle server的能力,就是生成的 bundle.js 文件可以通过 localhost://xxx 的方式去访问;
  • hot-module-replacement-plugin 的作用是提供 HMR 的 runtime,并且将 runtime 注入到 bundle.js 代码里面去。一旦磁盘里面的文件修改,那么 HMR server 会将有修改的 js module 信息发送给 HMR runtime,然后 HMR runtime 去局部更新页面的代码。因此这种方式可以不用刷新浏览器。
  • 简单来说就是:hot-module-replacement-plugin 包给 webpack-dev-server 提供了热更新的能力。
  • 这里面的热更新最核心的是 HMR Server 和 HMR runtime。HMR Server 是服务端,用来将变化的 js 模块通过 websocket 的消息通知给浏览器端。HMR Runtime是浏览器端,用于接受 HMR Server 传递的模块数据,浏览器端可以看到 .hot-update.json 的文件过来。webpack 构建出来的 bundle.js 本身是不具备热更新的能力的,HotModuleReplacementPlugin 的作用就是将 HMR runtime 注入到 bundle.js,使得bundle.js可以和HMR server建立websocket的通信连接。

流程图.jpg

  • express是用来起服务的;
  • ws 是websocket用来通信的;sockjs 是兼容ie9的,让IE9支持websocket,IE8 is not supported;
  • webpack-dev-server
  • webpack-dev-server依赖了webpack-dev-middleware;

  • webpack-dev-server 不刷新浏览器数据就会变化,不输出文件,而是放在内存中【webpack 将 bundle.js 文件打包到了内存中,不生成文件的原因就在于访问内存中的代码比访问文件系统中的文件更快,而且也减少了代码写入文件的开销,这一切都归功于内存文件系统 memfs,memfs 是 webpack-dev-middleware 的一个依赖库,webpack-dev-middleware 将 webpack 原本的 outputFileSystem 替换成了MemoryFileSystem 实例,这样代码就将输出到内存中。bundle.js 文件代码作为一个简单 javascript 对象保存在了内存中,当浏览器请求 bundle.js 文件时,devServer就直接去内存中找到上面保存的 javascript 对象返回给浏览器端】;

  • webpack-dev-server一般和 HotModuleReplacementPlugin一起用;

    • plugins: [ new webpack.HotModuleReplacementPlugin() ]
    • 其实devServer.hot 配置为true 就可以启动热更新;
  • 除了热更新,webpack-dev-server引用一个非常强大的http请求中间件http-proxy-middleware,此中间件能对http请求做中间转发处理,并且能够很好的解决了开发中跨域的问题;

  • webpack-dev-middleware

  文件指纹策略;

  • Chunkhash

和webpack打包的chunk有关,不同的entry会生成不同的 Chunkhash;一般用于js;

  • Contenthash

根据文件内容来定义hash,文件内容不变,Contenthash就不变;一般用于css;

  • Hash

和整个项目的构建有关,只要项目文件有修改,整个项目的hash值就会更改;

  • 图片和字体的hash

图片和字体的hash和js的hash不一样,图片和字体的hash是基于文件内容的hash,默认是md5生成;

Html css js代码压缩;

  • js 压缩

uglifyjs-webpack-plugin webpackV4版本内置了uglifyjs-webpack-plugin,只要是生产环境打包出来的js,默认会压缩;

  • Css 压缩

optimize-css-assets-webpack-plugin

Cssnano css的预处理器;

  • Html 压缩

html-webpack-plugin