什么是骨架:個人覺得:就是可以簡單打包css,js,html凉馆,這樣的使用場景比較多的是應用在于企業(yè)官網(wǎng)的開發(fā)低匙。
目標
開發(fā)一個官網(wǎng)坠七,你肯定不止一個頁面冷溶,所以我們需要多個頁面入口葛碧,多頁面出口設置。
比如
|---- build //存放webpack配置類似vue-cli生成的目錄
//打包結(jié)構(gòu)
|----dist
|---- index.html
|---- list.html
|---- css
|---- index.css
|---- list.css
|---- img
|---- js
|---- index.js
|---- list.js
// 目標結(jié)構(gòu)
|---- src
|---- modules // 存放公共文件
|---- css
|---- js
|---- pages
|---- index
|---- list
// html,css,js都放入對應的文件夾
Tips
我們不會只有一個簡簡單單的webpack.config.js
文件碟婆。我們想要高性能開發(fā)电抚,就需要分別配置開發(fā)環(huán)境與生產(chǎn)環(huán)境。所以我們最開始的目錄就是放在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'
}
}
- 知道了樣子,我們根據(jù)glob的遍歷的結(jié)果(結(jié)構(gòu)類似圖一)生成入口接口它長成的樣子:
/**** 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:'/'
}
}
到這里我們會發(fā)現(xiàn)只打包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劈彪,根據(jù)之前的多文件入口,我們可以這樣做:
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
}
結(jié)束
做到這里,我們的骨架就差不多完成了,可以打包基本js,css,html的文件灶芝,其中有些方方面面的細節(jié)沒有細說女器,大家可以到github上下載下來驾胆,自己改改玩玩~~~涣澡。
到這里明顯不夠,比如:為了適配es6語法的babel的配置,scss的配置驳阎,添加css的瀏覽器私有前綴蜘腌,webpack-dev-server開啟一個簡單的服務器......
之后會慢慢更新這一個系列芯急,歡迎大家點個star