重温webpack:骨架搭建

作者: 枸杞辣条 | 来源:发表于2017-12-18 11:02 被阅读83次

    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 + '/*/*')
    
    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'
         }
      }
    }
    
    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:骨架搭建

        本文链接:https://www.haomeiwen.com/subject/dmjzuxtx.html