webpack

2020-02-13  本文已影响0人  BingeryLamb
3CD14956-BB43-4C3D-8046-B31031ECD6C4.png
不推荐全局安装
npm install webpack webpack-cli -g
推荐项目中安装
npm install webpack webpack-cli -D
npx webpack -v  
npx帮助在当前项目的node_modules中找webpack

配置文件 webpack.config.js

module.exports = {}
mode: 'production',(默认模式 压缩)
//devtool: 'cheap-module-eval-source-map'(映射关系),
devtool: 'cheap-module-source-map',
entry: {
  main: './index.js',
  sub: './index.js',
},
devServer: { //ajax请求必须在http://下的index下
  //webpackDevMiddleware complier
  contentBase: './dist', //项目在电脑内存
  open: true,
  proxy: {
    '/api': 'http://localhost:3000' //跨域代理 
  },
  hot: true, //HMR
  hotOnly: true
},
modules: {
  rules: [
 {
    test: '/\.(js)$/',
    exclude: /node_modules/,
    loader: 'babel-loader',//babel与webpack的桥梁
    options: {  //可以写到.babelrc文件里面
      presents: [
      ['@babel/preset-env', { //翻译
        targets: {
          chrome: "67", //兼容到哪个版本的chrome 29kb
        },
        useBuiltIns: 'usage' //按需集成对象 161kb
      }]
     '@babel/preset-react' //由下而上
     ]
     //plugins: [['@babelplugins-transform-runtime', { //写库的方案
        //'corejs': 2,
        //'helpers': true,
        //'regenerator': true,
        //'useESModules': false
     //}]],
      plugins: ["@babel/plugin-syntax-dynamic-import"], //支持import异步加载
    }
  }, 
  {
    test: '/\.(jpg|png|gif)$/',
    use: { 
      loader: 'url-loader',
      options: {
        name: '[name].[ext] ',
        outputPath: 'images/',
        limit: 20480
      }
    }
  },
 {
    test: '/\.(eot|ttf|svg)$/',
    use: { 
      loader: 'file-loader',
    }
  },
 {
    test: '/\.less$/',
    use: { 
      loader: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            importLoaders: 2, //import的css也会走下面两个
            modules: true //css module / import style from './index.css' classList.add(style.title)
          }
        },
        'less-loader',
        'postcss-loader'
      ]
    }
  }
  ]
},
//plugin可以在webpack运行到某个时刻帮你做一些事情 就像生命周期
plugins: [
new HtmlWebpackPlugin({
  template: 'src/index.html'
}, 
new CleanWebpackPlugin(['dist' ], {
   root: path.resolve(__dirname, "../")
}), //打包结束后自动生成一个html文件并把js自动引入
new webpack.HotModuleReplacementPlugin(), //HMR 不要直接刷新 
//babel-present vue-loader css -loader 都内置了hmr的module.hot.accept代码
new webpack.ProvidePlugin({ // shimming 垫片
  $: 'jquery' //当发现模块里面用了$, 自动帮你引入jquery
})
],
optimization: {
  usedExports: true, //tree shaking 生产环自动生效不用配置
  splitChunks: { //code splitting 同步加载lodash代码分割 splitChunksPlugin 起到第二次加载的缓存性能优化
    chunks: 'all',
    cacheGroups: { //lodash分包取名生效
      vendors: false,
      default: false
    }
  }
},
output: { 
  publicPath: 'http://cdn.com.cn', 
  filename: '[name].[contenthash].js', // 浏览器缓存caching 
  chunkName: '[name].[contenthash].js',
  path: path.resolve(__dirname, '../dist'),
}
import '@babel/polyfill' 
// webpack配置后可去除这行代码
//为低版本浏览器集成promise map等所有对象一并打包 29kb->880kb
//如果只写个内库集成的对象会污染全局
//tree-shaking 引入什么打包什么 只支持es module这种静态引入的方式 
package.json
{
  'sideEffects':["@babel/polly-fill", "*.css"], 
  //import "@babel/polly-fill" tree-shaking可能就忽略掉了 因为没有导出任何内容 
function getComponent() {
  //注释分包取名
  return import(/* webpackChunkName: "lodash"*/'lodash').then(({ default: _ })=>{ //异步加载lodash 自动代码分割打包
    var element = document.createElement('div')
    element.innerHTML = _.join(['Dell', 'Lee'], '-')
    return element
  })
  //const {default: _} = await import (/* webpackChunkName: "lodash"*/'lodash')
}
getComponent().then(element => {
  document.body.appendChild(element)
})
懒加载
document.addEventListener('click', ()=>{
  getComponent().then(element => {
    document.body.appendChild(element)
  })
})
打包分析
chrome coverage 代码使用率
document.addEventListener('click', ()=>{
   var element = document.createElement('div')
   element.innerHTML = 'Dell Lee'
   document.body.appendChild(element)
})
不会执行的代码你让页面去下载下来就会浪费页面执行的性能 应该把它放到异步加载的模块里来写
// click.js
function handleClick() {
   var element = document.createElement('div')
   element.innerHTML = 'Dell Lee'
   document.body.appendChild(element)
}
export default handleClick
document.addEventListener('click', ()=>{
   import('./click.js').then(({default: func})=>{
      func()
   })
})
多写异步代码才能让网站性能得到真正意义上的提升 同步分割只是增加一个缓存 意义不大

preloading prefetching
在网络空闲就去下载交互代码 而不是点击时才下载 最优方案
document.addEventListener('click', ()=>{
   // 魔法注释
   import(/* webpackPrefech: true*/'./click.js').then(({default: func})=>{
      func()
   })
})
上一篇下一篇

猜你喜欢

热点阅读