zoukankan      html  css  js  c++  java
  • webpack学习(三)

    module:就是js的模块化webpack支持commonJS、ES6等模块化规范,简单来说就是你通过import语句引入的代码。

    chunk: chunk是webpack根据功能拆分出来的,包含三种情况:

        1、你的项目入口(entry)

        2、通过import()动态引入的代码

        3、通过splitChunks拆分出来的代码

        chunk包含着module,可能是一对多也可能是一对一。

    bundle:bundle是webpack打包之后的各个文件,一般就是和chunk是一对一的关系,bundle就是对chunk进行编译压缩打包等处理之后的产出。

    一、优化

    1.noParse: 不去解析属性值代表的库的依赖

    表示在打包的时候不用再去深度解析某个第三方库中的依赖包,类似jq这类依赖库,一般会认为不会引用其他的包(特殊除外,自行判断)。所以,对于这类不引用其他的包的库,我们在打包的时候就没有必要去解析,这样能够增加打包速率。

     2.IgnorePlugin

    表示忽略第三方包指定目录,让这些指定目录不要被打包进去

    这是webpack自带的一个插件

    比如我们要使用moment这个第三方依赖库,该库主要是对时间进行格式化,并且支持多个国家语言。在打包的时候,是会将所有语言都打包进去的。这样就导致包很大,打包速度又慢我们可以用这个插件忽略掉这些语言的打包,然后手动引入需要的语言包

    plugins:[
            //webpack自带插件,从moment中引入的时候忽略掉语言
            new webpack.IgnorePlugin(/./locale/,/moment/),
            new htmlWebpackPlugin({
                template: './public/index.html'
            })
        ]

    index.js

    import moment from 'moment'
    //设置语言 忽略之后不再生效需要
    // moment.locale('zh-cn')
    //这时候需要手动引入需要的语言
    import 'moment/locale/zh-cn'
    let r = moment().endOf('day').fromNow() //距离今天结束还有几小时
    console.log(r)

    没有忽略语言包之前的大小

     忽略掉语言包之后的大小

    3. DllPlugin 

    这块没看懂,推荐这篇文章:https://www.cnblogs.com/tugenhua0707/p/9520780.html

    4.Happypack 多进程打包

    在使用 Webpack 对项目进行构建时,会对大量文件进行解析和处理。当文件数量变多之后,Webpack 构件速度就会变慢。由于运行在 Node.js 之上的 Webpack 是单线程模型的,所以 Webpack 需要处理的任务要一个一个进行操作。

    而 Happypack 的作用就是将文件解析任务分解成多个子进程并发执行。子进程处理完任务后再将结果发送给主进程。所以可以大大提升 Webpack 的项目构件速度

    由于 JavaScript 是单线程模型,要想发挥多核 CPU 的能力,只能通过多进程去实现,而无法通过多线程实现。

    HappyPack 对file-loader、url-loader 支持的不友好,所以不建议对该loader使用。

    之前打包js用的是这些loader

    现在需要happypack

     

    当项目体积庞大的时候用多进程打包会加快打包速率,小体积项目反而会降低打包速率,因为分配时进程本身也需要花费时间。

    happypack原理请看这篇文章:https://segmentfault.com/a/1190000021037299?utm_source=tag-newest

    5.webpack自带优化工具

    • tree-shaking 会自动将没用到的代码删除掉
    test.js

    function
    sum (a, b) { return a+b } function minus (a, b) { return a-b } export default{ sum, minus }
    index.js
    import calc from './test' console.log(calc.sum(1,2))
    此时我们只用到了sum方法,minus方法没有用到
    在生产环境下打包会自动清除minus方法,这就是tree-shaking 会自动将没用到的代码删除掉
    而且必须是以import引入的文件
    要是以require引入的就不会清除
    • scope hosting 作用域提升  
    let a = 1
     let b = 2
     let c = 3
     let d = a+b+c //webpack会自动省略可以简化的代码
    console.log(d+'------')

     6.抽取公共代码

    如果某个js文件被多个js代模块引用就可以将这个公共的代码块分割出去,打包成一个公共文件,代码分割是基于浏览器会缓存你的代码这一事实。每当你对某一文件做点改变,访问你站点的人们就要重新下载它。然而依赖却很少变动。如果你将(这些依赖)分离成单独的文件,访问者就无需多次重复下载它们了。

    假设有两个页面indexother,现在这两个文件都需要引入a.js和b.j,如果不分割,这两个页面就都会有a.js的内容和b.js的内容,抽取之后这些公共内容将会放在一个common.js中,然后indexother各自的页面只包含自己的那部分内容,这个时候我们就可以这么配置了

    entry: { 
          index: './src/index.js',
          other: './src/other.js'
        },
        output: {
            filename: '[name].js',
            path:path.resolve(__dirname,'dist')
        },
        module:{
          optimization:{ 
            splitChunks:{ //分割代码
              cacheGroups:{ //缓存组
                common:{ //公共模块
                  chunks:'initial', //chunks有三个参数,initial表示只从入口模块进行拆分 async表示只从异步加载得模块(动态加载import())里面进行拆分 all表示以上两者都包括
                  minSize:0, //表示在压缩前的最小模块大小
                  minChunks:2 //只要超过2次以上引用就抽离
                 },
              }
            }
          },

    打包后的结果如下:

    有时候我们还需要引入第三方模块,比如jquery等,这个时候也需要抽离这些第三方模块。如下配置:

    entry: { 
          index: './src/index.js',
          other: './src/other.js'
        },
        output: {
            filename: '[name].js',
            path:path.resolve(__dirname,'dist')
        },
        module:{
          optimization:{ 
            splitChunks:{ //分割代码
              cacheGroups:{ //缓存组
                common:{ //公共模块
                  chunks:'initial', //chunks有三个参数,initial表示只从入口模块进行拆分 async表示只从异步加载得模块(动态加载import())里面进行拆分 all表示以上两者都包括
                  minSize:0, //表示在压缩前的最小模块大小
                  minChunks:2 //只要超过2次以上引用就抽离
                 },
                 vendor:{ //抽离第三方模块
                  priority:1, //表示先抽离第三方模块再抽离公共模块,不加这个的话第三方模块将和公共模块放在一起,不太好
                  test:/node_modules/, //从node_modules里面抽取
                  chunks:'initial', 
                  minSize:0, //表示在压缩前的最小模块大小
                  minChunks:2 //只要超过2次以上引用就抽离
                }
              }
            }

    打包结果:

     

     7.懒加载

    有时候我们会点击某个按钮再去加载对应的资源,也可以理解成是异步加载某个资源,如下代码:

    let button = document.createElement('button')
    button.innerHTML = 'hello'
    
    //点击按钮加载资源
    button.addEventListener('click',function(){ 
        //es6草案语法  其原理是jsonp实现动态加载文件
        import('./source.js').then(data=>{
            console.log(data)
        })
    })
    document.body.appendChild(button)

    再点击按钮之后通过import加载了source.js文件,返回一个promise,就可拿到这个文件里的内容

     8.热更新

    我们希望在页面发生了变化的时候只更新那一部分变化了的内容,而不是整个全部刷新。

    webpack.config.js配置

    devServer:{
          hot:true, //启用热更新
          port:3000,
          open:true,
          contentBase: './dist'
        },
    plugins:[new webpack.HotModuleReplacementPlugin(), //热更新插件
            new webpack.NamedModulesPlugin() //告诉哪个模块更新了
        ]

    index.js

    import str from './source.js'
    console.log(str)
    if(module.hot) {
      module.hot.accept('./source.js',()=>{
        //import只能写在页面的顶端
        let str = require('./source.js')
        console.log(str.default)
      })
    }

    当source.js内容发生了变化就不会刷新整个页面了而是更新一部分

    当然最好能搞懂热更新的原理 

     

    不积跬步无以至千里
  • 相关阅读:
    EOF ---shell编程
    Linux错误代码含义
    linux连接sybase数据库-isql
    CH7-WEB开发(集成在一起)
    [转]ASP.NET MVC 入门10、Action Filter 与 内置的Filter实现(实例-防盗链)
    [转]ASP.NET MVC 入门9、Action Filter 与 内置的Filter实现(介绍)
    [转]ASP.NET MVC 入门8、ModelState与数据验证
    [转]ASP.NET MVC 入门7、Hellper与数据的提交与绑定
    [转]ASP.NET MVC 入门6、TempData
    [转]ASP.NET MVC 入门5、View与ViewData
  • 原文地址:https://www.cnblogs.com/lyt0207/p/12559536.html
Copyright © 2011-2022 走看看