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里面js是第一公民,所以只需要在glob.sync(PAGE_PATH + '/*/*.js')
加一层过滤就好了。
- 首先,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
- 单独打包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'
})
}
- 单独打包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