重温webpack:骨架搭建

github 地址 找到skeleton分支

什么是骨架:个人觉得:就是可以简单打包css,js,html,这样的使用场景比较多的是应用在于企业官网的开发。

目标

开发一个官网,你肯定不止一个页面,所以我们需要多个页面入口,多页面出口设置。
比如

|---- build //存放webpack配置类似vue-cli生成的目录
 //打包结构
|----dist
      |---- index.html
      |---- list.html
      |---- css
             |---- index.css
             |---- list.css
      |---- img
      |---- js
             |---- index.js
             |---- list.js
// 目标结构
|---- src
       |---- modules // 存放公共文件
                |---- css
                |---- js
       |---- pages
               |---- index
               |---- list
// html,css,js都放入对应的文件夹

Tips

我们不会只有一个简简单单的webpack.config.js文件。我们想要高性能开发,就需要分别配置开发环境与生产环境。所以我们最开始的目录就是放在build文件夹下面。记得我之前学习如何打包的时候都是直接输入webpack打包。但是我们可以看vue脚手架的script是直接运行node ./build/build.js(我们暂且不讲dev-server),而它的根本的是运行这一段。
所以我们要先npm i webpack -D

如何配置自动化的多入口多出口文件

我们需要用到glob的依赖。glob的使用在于遍历某个文件夹下面的所有文件。
我们只需要知道简单的使用

// 比如在我的电脑
const path = require('path')
const PAGE_PATH = path.resolve(__dirname, '../src/pages')
entryFiles = glob.sync(PAGE_PATH + '/*/*')
重温webpack:骨架搭建_第1张图片
glob会打出匹配目录下面的所有文件

当然在webpack里面js是第一公民,所以只需要在glob.sync(PAGE_PATH + '/*/*.js')加一层过滤就好了。

图一.png

  • 首先,webpack入口长什么样子的?
// 大概是
{
  entry:{
   index:'index path',
   list:'list path'
 }
}
  • 知道了样子,我们根据glob的遍历的结果(结构类似图一)生成入口接口它长成的样子:
/**** utiles ****/
const path = require('path')
const glob = require('glob')
const PAGE_PATH = path.resolve(__dirname,'../src/pages/')

const entries = function(){
  let entryFiles = glob.sync(PAGE_PATH+'/*/*.js')
  let map = {}
  entryFiles.forEach(filePath=>{
    let filename = filePath.substring(filePath.lastIndexOf('\/') + 1,filePath.lastIndexOf('.'))
    //多目录下有多个js文件进行过滤
    let arr = filePath.split('\/')
    if(arr[arr.length-2]===filename){
      map[filename] = filePath
    }
  })
  return map
}
entries()
module.exports={
  entries
}
  • 入口解决完了,出口还不是分分钟吗?
{
  output:{
    filename:'js/[name].js', //[name]代表的是entry的key值
    path: path.resolve(__dirname, '../dist') //定义输出文件夹,
    publicPath:'/'
  }
}

到这里我们会发现只打包js。接下来就是配置各种loader,当然还有最重要的,如何单独打包出css,html文件

  • 配置loader
module{
  rule:{
      {
        test: /\.css$/,
        use: ['style-loader','css-loader']
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'img/[name].[hash:7].[ext]'
            }
          }
        ]
      },
     {
       test: /\.html$/,
       use:'html-loader'
     }
  }
}
  • 当然只有以上操作的话打包的也只有js文件。
    我们需要额外的插件来单独分离出我们的css,html
    extract-text-webpack-loader
    html-webpack-plugin
  1. 单独打包css
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')
// 插件项目
plugins: [
  new ExtractTextWebpackPlugin('css/[name].css') // 类似于output的filename
]
// rules里面的loader的修改
{
  test: /\.css$/,
  use: ExtractTextWebpackPlugin.extract({
    fallback:'style-loader',
    use: 'css-loader'  
  })
}
  1. 单独打包html
    这一步会比较麻烦,首先,webpack怎么知道你要加载的哪些css?因为可以在对应的js文件下import进来,如何知道需要哪些js对应的哪些html就需要手动配置了。并且因为我们设置的是自动化多页面入口,当然出口也是自动化的。
    先说一下html-webpack-plugin如何使用吧
  new HtmlWebpackPlugin({
     filename: 'index.html', // 类似于output的filename
     template: path.resolve(__dirname, '../src/index.html'), // 文件位置
     chunks: 'index', // 依赖的js
   }),

前面我们可以通过glob把所有路径解析成类似图一,要生成类似以上模板,最主要要得到的就是文件位置也就是template,根据之前的多文件入口,我们可以这样做:

exports.htmlPlugins=function(){
  let entryHtml = glob.sync(PAGE_PATH+'/*/*.html')
  let arr = []
  entryHtml.forEach(filePath=>{
    let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
    let conf = {
      filename:filename+'.html',
      template:path.resolve(PAGE_PATH,filename+'/'+filename+'.html'),
      chunks:[filename],
      inject:true,
    }
    arr.push(new HtmlWebpackPlugin(conf))
  })
  return arr
}

结束

做到这里,我们的骨架就差不多完成了,可以打包基本js,css,html的文件,其中有些方方面面的细节没有细说,大家可以到github上下载下来,自己改改玩玩~~~。
到这里明显不够,比如:为了适配es6语法的babel的配置,scss的配置,添加css的浏览器私有前缀,webpack-dev-server开启一个简单的服务器......

之后会慢慢更新这一个系列,欢迎大家点个star

你可能感兴趣的:(重温webpack:骨架搭建)