溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

詳解如何快速配置webpack多入口腳手架

發(fā)布時間:2020-09-13 09:46:06 來源:腳本之家 閱讀:283 作者:盧溝曉月 欄目:web開發(fā)

背景

當我們基于vue開發(fā)單個項目時,我們會init一個vue-cli,但當我們想在其他項目里共用這套模板時,就需要重新init一個,或者clone過來,這非常不方便,而且當多人開發(fā)時,我們希望所有的開發(fā)代碼都在一個git目錄下,這時就有了對webpack進行配置的需求,當有些頁面需要多入口時,我們又產(chǎn)生了對多入口配置的需求,這里提供一種配置方案,希望能幫助到有需要的人,廢話不多說,我們開始吧!

先初始化一個項目

我們通過vue init webpack demo 生成的文件目錄是這樣的

詳解如何快速配置webpack多入口腳手架

修改項目入口

要改多入口,首先改造一下 webpack.base.conf.js 中的 contextentry

context:基礎目錄,絕對路徑,用于從配置中解析入口起點(entry point)和 loader。

entry:起點或是應用程序的起點入口。從這個起點開始,應用程序啟動執(zhí)行。

module.exports = {
 context: path.resolve(__dirname, '../'),
 entry: {
  app: './src/main.js'
 },
};

如果項目只有一個入口,那么直接在這里改entry就可以了,但一般我們都是多個項目在放一個目錄里,所以要提取出來context和entry。

const paths = require('./paths')
const rootPath = paths.rootPath
module.exports = {
 context: rootPath
 entry: {
  app: utils.getEntry(),
 }, 
};

在config里新建 _config.js 和 paths.js

_config.js ,用于設置當前啟動項目,并將這個文件添加到.gitignore中,因為以后多人開發(fā)都是在本地修改項目地址。

'use strict'
 module.exports = {
 appName: 'mobile',
 projectName: 'demo'
}

這里設計2個目錄,appName是src下的一級目錄,projectName是appName下的二級目錄,目的在于方便拓展,比如公司的項目分為pc項目和mobile項目,開發(fā)時便于區(qū)分,如果你的項目比較少,那可以把appName寫成一個固定字符串如:pages,每次切換項目只更改projectName就可以了。我們將所有項目放在src下,類似目錄如下

├─mobile
│ ├─demo
│ └─demo2
└─pc
  ├─demo
  └─demo2

paths.js ,用于配置一些全局需要用到的路徑

'use strict'
const path = require('path')
const fs = require('fs')
const _config = require('./_config')

const rootPath = fs.realpathSync(process.cwd()) // 項目根目錄 fs.realpathSync表示獲取真實路徑
const resolve = relativePath => path.resolve(rootPath, relativePath) // 自定義一個resolve函數(shù),拼接出需要的路徑地址
module.exports = {
 rootPath, // 項目根目錄
 commonPath: resolve('common'), // 公共目錄
 projectPath: resolve(`src/${_config.appName}/${_config.projectName}`), // 子項目根目錄
 config: resolve('config'), // 項目配置
 static: resolve('static') // 公共靜態(tài)資源目錄
}

新建common文件夾

我們在src同級新建一個common文件夾,用于存放靜態(tài)資源及公共組件

-components 
 ├─assets
 ├─components
 └─xhr

assets里可以存放公共樣式css,公共字體font,公共圖片img,公共方法js等;components里存放提取出來的公共組件,xhr我放的是axio的封裝,整個文件夾可以自定義修改,這里就不展開了,如果項目比較簡單不需要,在paths.js里刪去對應的部分即可。

再來看我們修改的entry,我們在config文件夾中的utils.js 新增了getEntry方法,并在entry處引用。

'use strict'
// 省略...
const paths = require('./paths')
const fs = require('fs')
// 省略...
exports.getEntry = () => {
 const entryPath = path.resolve(paths.projectPath, 'entry')
 const entryNames = fs
   .readdirSync(entryPath)
   .filter(n => /\.js$/g.test(n))
   .map(n => n.replace(/\.js$/g, ''))
 const entryMap = {}

 entryNames.forEach(
   name =>
   (entryMap[name] = [
     ...['babel-polyfill', path.resolve(entryPath, `${name}.js`)]
   ])
 )
 return entryMap
}

實際上就是對當前項目entry文件中的js文件進行遍歷,如果是單個就是單入口,多個就是多入口。

創(chuàng)建2個項目

詳解如何快速配置webpack多入口腳手架

  • assets 靜態(tài)資源
  • config.js 代理配置、打包地址等配置
  • entry 入口文件夾

demo1是一個單入口項目,demo2是一個多入口項目,如果是多入口項目,需要在entry增加對應的js文件,如上圖中的more.html和more.js,上面的getEntry其實找的就是index.js和more.js。

我們再看一下demo2中entry中的index.js和more.js

// index.js
import Vue from 'vue'
import App from '../App'

new Vue({
 el: '#app',
 router,
 components: { App },
 template: '<App/>'
})
// more.js
import Vue from 'vue'
import App from '../More'

new Vue({
 el: '#more',
 components: { App },
 template: '<App/>'
})

引入對應的組件就好,再看下config.js

const host = 'http://xxx.com/api' // 測試地址

module.exports = {
 dev: {
  // proxy代理配置
  proxyTable: {
   '/api': {
    target: host, // 源地址
    changeOrigin: true, // 改變源
    logLevel: 'debug',
    ws: true,
    pathRewrite: {
     '^/api': '' // 路徑重寫
    }
   }
  },
  build: {
   // build輸出路徑
   // assetsRoot: path.resolve(process.cwd(), '')
  }
  // 是否啟用postcss-pxtorem插件 https://github.com/cuth/postcss-pxtorem
  // pxtorem: true
 }
}

這里就是根據(jù)需要自行配置了,如果不需要完全可以不要這個文件,重要的還是entry的入口文件。

打包出口配置

入口改好了,我們再看出口,找到如下內(nèi)容

// webpack.dev.conf.js
plugins: [
  new webpack.DefinePlugin({
   'process.env': require('../config/dev.env')
  }),
  new webpack.HotModuleReplacementPlugin(),
  new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
  new webpack.NoEmitOnErrorsPlugin(),
  // https://github.com/ampedandwired/html-webpack-plugin
  new HtmlWebpackPlugin({
   filename: 'index.html',
   template: 'index.html',
   inject: true
  }),
  // copy custom static assets
  new CopyWebpackPlugin([
   {
    from: path.resolve(__dirname, '../static'),
    to: config.dev.assetsSubDirectory,
    ignore: ['.*']
   }
  ])
 ]
// webpack.prod.conf.js
new HtmlWebpackPlugin({
   filename: config.build.index,
   template: 'index.html',
   inject: true,
   minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeAttributeQuotes: true
    // more options:
    // https://github.com/kangax/html-minifier#options-quick-reference
   },
   // necessary to consistently work with multiple chunks via CommonsChunkPlugin
   chunksSortMode: 'dependency'
  }),
// 省略
// copy custom static assets
  new CopyWebpackPlugin([
   {
    from: path.resolve(__dirname, '../static'),
    to: config.build.assetsSubDirectory,
    ignore: ['.*']
   }
  ])

HtmlWebpackPlugin的作用是生成一個 HTML5 文件,CopyWebpackPlugin的作用是將單個文件或整個目錄復制到構建目錄。我們在utils.js中新建2個方法getHtmlWebpackPlugin和getCopyWebpackPlugin,對這兩個方法進行替換,讓他們支持多入口。改動后如下

// webpack.dev.conf.js
 plugins: [
  new webpack.DefinePlugin({
   'process.env': require('./dev.env')
  }),
  new webpack.HotModuleReplacementPlugin(),
  new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
  new webpack.NoEmitOnErrorsPlugin(),
  // https://github.com/ampedandwired/html-webpack-plugin
  // 改動
  ...utils.getHtmlWebpackPlugin(baseWebpackConfig),
  // copy custom static assets
  // 改動
  ...utils.getCopyWebpackPlugin()
 ]
// webpack.prod.conf.js
  // 改動
   ...utils.getHtmlWebpackPlugin(baseWebpackConfig),
  // 省略
  // 改動
   ...utils.getCopyWebpackPlugin()
// utils.js
exports.getHtmlWebpackPlugin = baseWebpackConfig => {
 const HtmlWebpackPluginList = []
 const entryNames = Object.keys(baseWebpackConfig.entry)
 entryNames.forEach(name => {
   HtmlWebpackPluginList.push(
     new HtmlWebpackPlugin(
       Object.assign({
           filename: config.build.filename && process.env.NODE_ENV == 'production' ? config.build.filename : `${name}.html`,
           template: config.build.template && process.env.NODE_ENV == 'production' ? path.resolve(
             paths.projectPath, config.build.template) : path.resolve(
             paths.projectPath,
             `${name}.html`
           ),
           inject: true,
           excludeChunks: entryNames.filter(n => n !== name)
         },
         process.env.NODE_ENV === 'production' ? {
           minify: {
             removeComments: true,
             collapseWhitespace: true
               // removeAttributeQuotes: true
           },
           chunksSortMode: 'dependency'
         } : {}
       )
     )
   )
 })
 return HtmlWebpackPluginList
}

exports.getCopyWebpackPlugin = () => {
 const projectStaticPath = path.resolve(paths.projectPath, 'static')
 const assetsSubDirectory =
   process.env.NODE_ENV === 'production' ?
   config.build.assetsSubDirectory :
   config.dev.assetsSubDirectory
 const rootConfig = {
   from: paths.static,
   to: assetsSubDirectory,
   ignore: ['.*']
 }
 const projectConfig = {
   from: projectStaticPath,
   to: assetsSubDirectory,
   ignore: ['.*']
 }
 return [
   new CopyWebpackPlugin(
     fs.existsSync(projectStaticPath) ? [rootConfig, projectConfig] : [rootConfig]
   )
 ]
}

修改index.js

我們找到config里index.js,對其做一些修改,讓我們可以在項目里的config.js中配置代理,打包目錄,讓模板更靈活。

// config/index.js 改造前
 dev: {
  // Paths
  assetsSubDirectory: 'static',
  assetsPublicPath: '/',
  proxyTable: {},
  // Various Dev Server settings
  host: 'localhost', // can be overwritten by process.env.HOST 
 },
 build: {
  // Template for index.html
  index: path.resolve(__dirname, '../dist/index.html'),

  // Paths
  assetsRoot: path.resolve(__dirname, '../dist'),
  assetsSubDirectory: 'static',
  assetsPublicPath: '/',
  // 省略
 }
//config/index.js 改造后
const paths = require('./paths')
const resolve = relativePath => path.resolve(paths.projectPath, relativePath)
const _config = require(resolve('config.js')) // 子項目webpack配置
 dev: {
  // Paths
  assetsSubDirectory: 'static',
  assetsPublicPath: '/',
  proxyTable: _config.dev.proxyTable,
  // Various Dev Server settings
  host: '0.0.0.0', // can be overwritten by process.env.HOST 
 },
 build: {
  // Template for index.html
  index: path.resolve(__dirname, '../dist/index.html'),

  // Paths
  assetsRoot: _config.build.assetsRoot || path.resolve(__dirname, '../dist'),
  assetsSubDirectory: 'static',
  assetsPublicPath: _config.build.publichPath || './',
  // 省略
 }

到這里,我們的多入口配置就基本完成了,注意修改過的配置文件里一些引用需要加上,檢查下路徑是否正確。

既然我們的目的就是打造多入口模板,那么以demo2為例,運行npm run dev 在如果服務是http://localhost:8080,多頁面入口在瀏覽器訪問時url就是http://localhost:8080/more.html。注意要帶.html哦。

運行npm run build 我們會發(fā)現(xiàn)dist文件夾里有2個html,說明多入口打包成功

詳解如何快速配置webpack多入口腳手架

到此我們的項目模板就配置完成了。以后多人開發(fā)、多入口活動都可以在這個項目下進行開發(fā)了,此篇不涉及webpack優(yōu)化,只提供一種配置思路。如果感覺文章寫的不夠清楚,或者想直接使用這個模板,我的git上有完整的腳手架

傳送門 ,如果遇到問題或者好的建議,歡迎提出。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI