webpack | 进阶用法1:多入口构建/资源内联/脚本分离等

217 阅读2分钟

这是我参与更文挑战的第27天,活动详情查看:更文挑战

[webpack系列文章连载中...]

1. 多入口构建

动态构建entry和创建多入口HTML模板文件。

Glob

glob模块,允许使用**等符号编写一个glob规则,匹配对应规则的文件。基础用法如下:

// 文件:glob.js

// 异步写法
var glob = require('glob')
var path = require('path')
var matchFilePattern = path.resolve(__dirname, "*.js"
// 匹配出当前目录下所有的js文件
glob(matchFilePattern), function (er, files) {
    console.log(files)
    //[D:/webpackDemo/src/glob.js]
})

// 同步写法
var files = glob.sync(matchFilePattern)

多入口构建脚本

const glob = require('glob')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

const setMPA = ()=>{
  const entry = {}
  const htmlWebpackPlugins = []
  // 匹配src目录下所有的index.js文件作为入口文件
  const entryFiles = glob.sync(__dirname,'./src/*/index.js')
  
  Object.keys(entryFiles).map((index)=>{
    const entryFile = entryFiles[index]
    // 通过文件绝对路径匹配出文件名
    const match = entryFile.match(/src\/(.*)\/index\.js/)
    const pageName = match && match[1]
    // 构建webpack的entry配置
    entry[pageName] = entryFile
    htmlWebpackPlugins.push(
    	new HtmlWebpackPlugin({
      	template:path.join(__dirname,`src/${pageName}/index.html`),
        filename:`${pageName}.html`,
        chunks:[pageName],
        inject:true,
        minify:{
          html5:true,
          collapseWhitespace:true,
          preserveLineBreaks:false,
          minifyCSS:true,
          minifyJS:true,
          removeComments:false
        }
      })
    )
  })
  return {
    entry,
    htmlWebpackPlugins
  }
}

const {entry,htmlWebpackPlugins} = setMPA()

2. CSS相关处理和移动端px转rem

1. CSS3自动补前缀

通过PostCSS插件

{
  test:/.less$/,
  use:[
  	MiniCssExtractPlugin.loader,
    'css-loader',
    'less-loader',
    {
    	loader:'post-loader',
      options:{
      	plugins:()=>{
        	require('autoprefixer')({
          	browsers:['last 2 version','>1%','ios 7']
          })
        }
      }
    }
  ]
}

2. 移动端适配

  1. 采用CSS媒体查询实现响应式布局
@media screen and (max-width:980px){
	.header{width:900px}
}
@media screen and (max-width:480px){
  .header{width:400px}
}
@media screen and (max-width:350px){
  .header{width:300px}
}
  1. px转rem

rem是相对单位,px是绝对单位。

实现:使用px2rem-loader和手淘的lib-flexible库(页面渲染时计算根元素的font-size值)

{
  test:/.less$/,
  use:[
    MiniCssExtractPlugin.loader,
    'css-loader',
    'less-loader',
    {
      loader:'post-loader',
      options:{
      	plugins:()=>{
             require('autoprefixer')({
             browsers:['last 2 version','>1%','ios 7']
          })
        }
      }
    },
    {
      loader:'px2rem-loader',
      options:{
      	remUnit:75,
        remPrecision:8
      }
    }
  ]
}

3. 资源内联

资源内联的好处有:

  1. 页面框架的初始化脚本

  2. 上报相关打点

  3. css内联避免页面闪动

  4. 减少HTTP网络请求数(小图片或字体内联url-loader)

<!--1. raw-loader 内联html--> 
<script>${require('raw-loader!babel-loader!./meta.html')}</script>

<!--2. raw-loader 内联js--> 
<script>${require('raw-loader!babel-loader!../node_modules/lib-flexible')}</script>

<!--3. CSS内联 style-loader -->
module.exports = {
   module:{
    rules:[
    	{
      	test:/\.scss$/,
        use:[
         {
            loader:'style-loader',
            options:{
              insertAt:'top',  // 样式插入到<head>
              singleton:true,  // 将所有的style标签合并成一个
            }
          },
          'css-loader',
          'sass-loader'
        ]
      }
    ]
  }
}

<!--4. CSS内联  使用:html-inline-css-webpack-plugin -->

4. 脚本分离

{
   optimization:{
  	splitChunks:{
      // 'async':异步引入的库进行分离(默认)
      // 'initial':同步引入的库进行分离
      // 'all':所有引入的库进行分离
      chunks:'all',
      // 分离的包体积的大小
      minSize:0, 
      cacheGruops:{
        // 分离页面公共文件
      	commons:{
          name:'commons',
          chunks:'all',
          minChunks:2 // 设置最小引用次数
        },
        // 公共脚本分离
        vendors:{
          test:/[\\/]nodule_modules[\\/]/,
          priority:-10
        },
        // 分离基础包
        library:{
          test:/(react|react-dom)/,
          name:'library',
          chunks:'all'
        }
      }
    }
  }
}

5. 总结

至此学习了webpack进阶用法1,下一章学习:代码分割和引入,打包js库以及SSR等。