用vue的都知道vue-cli是一個強大的構建vue項目的工具。vue-cli3.0前,它全部的配置都能看到,到vue-cli3.0後全部的配置都隱藏了。最近恰好有點空閒時間,就試着開始搭建了一個本身的vue-cli。這個是第一步:基於webpack4搭建基本的vue開發環境。css
配置過程當中能夠參照我配置好滴:vue-cli-forLoghtml
由於是基於webpack4的,最好在開始配置前須要確保安裝了Node.js
是最新版本。 首先新建一個文件夾就叫myvue-cli
吧,cd myvue-cli
以後運行如下命令vue
npm init -y
npm install webpack webpack-cli --save-dev
複製代碼
由於是基於webpack4的因此要安裝webpack-cli,且webpack不推薦全局安裝,這樣會指定webpack的版本,使在不一樣的webpack版本中構建時失敗。node
下一步修改package.json文件,添加"private": true
移除"main": "index.js"
,以確保安裝包是私有的,且不會意外發布代碼。webpack
新建一個build文件夾來存放配置文件,由於項目是要分還發環境和生產環境的,因此咱們要把生產環境和開發環境的配置文件區分,又由於有些配置是公共的,因此須要一個公共配置文件,再經過webpack-merge
來合併配置文件。git
webpack.base.conf.js
:最基本的配置github
webpack.dev.conf.js
:開發環境的配置web
webpack.prod.conf.js
:生產環境的配置vue-cli
新建src/main.js
做爲入口文件 新建public/index.htm
做爲插入模板。index.html
文件內容能夠本身編寫好npm
以上的準備好以後就能夠慢慢滴來編寫webpack的配置了。
webpack配置最最最主要的就是入口和輸出了。so~在webpack.base.conf.js
個人配置以下
entry: {
app: './src/main.js'
}
output: {
path: path.resolve(__dirname, '../dist'),
filename: 'js/[name].js'
}
複製代碼
接下來就要對資源進行管理了。加載css、js、vue,圖片等,天然須要安裝相應的loader
咯
npm i --save-dev style-loader css-loader vue-loader vue-style-loader vue-template-compiler url-loader babel-loader eslint-loader
複製代碼
css:style-loader
css-loader
js:babel-loader
vue:vue-loader
vue-style-loader
vue-template-compiler
管理圖片字體:url-loader
或file-loader
eslint代碼校驗規範:eslint-loader
安裝好loader以後就能夠配置了。
babel 7.x以上的要配合安裝@babel/core @babel/preset-env
,presets已再也不使用babel-preset-2015
,而是使用@babel/preset-env
取代
.babelrc
{
"presets": [
"@babel/preset-env"
]
}
webpack.base.conf.js
{
test: /\.js?$/,
use: 'babel-loader',
exclude: file => (
/node_modules/.test(file) &&
!/\.vue\.js/.test(file)
)
}
複製代碼
eslint有助於咱們的代碼規範。網上有不少配置好的很規範的規則,拿來用便可。就不用咱們本身去定製,固然你想本身定製也能夠。 在這我是用的是標準的(standard)eslint規則 因爲須要在 Vue 單文件組件的模板和腳本部分的代碼校驗,還須要安裝官方的eslint-plugin-vue
. 爲了使eslint錯誤提示更美觀,更詳細我還安裝了eslint-formatter-pretty
插件
.eslintrc.js
...省略
parserOptions: {
parser: 'babel-eslint'
},
extends: [
"plugin:vue/essential",
"standard"
]
...
webpack.base.conf.js
{
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
options: {
formatter: require('eslint-formatter-pretty')
},
exclude: /node_modules/
}
複製代碼
關於vue-loader的配置就很少說了,能夠直接查看官網:vue-loader
關於樣式前綴自動補充配置
須要安裝postcss-loader autoprefixer
同時還要添加.postcssrc.js
配置文件
.postcssrc.js
plugins: {
autoprefixer: {}
}
或
plugins: [
require('autoprefixer')
]
webpack.base.conf.js
{
test: /\.css$/,
use: ["style-loader", "css-loader", "postcss-loader"]
}
複製代碼
還有個要注意的點:配置完成會你可能發現並無自動添加前綴;這是因爲autoprefixer會根據當前環境自動添加的。因此須要在package.json
文件添加一點配置來保證打包的css會自動添加前綴
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
複製代碼
若是你的項目使用了@import
來導入css,那麼css-loader
的配置參數importLoaders
須要大於1。options: { importLoaders: 2 }
。 其它的一些loader配置通常不會有什麼坑,就不說了。
plugins
了html-webpack-plugin
插件,這個插件會默認生成index.html,如須要插入到本身指定的html文件,配置一下便可,具體可查閱html-webpack-plugin 列入插入到先前新建的public/index.html
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.join(__dirname, '..', 'public/index.html')
})
複製代碼
要打包前清空上一次dist文件可以使用clean-webpack-plugin
插件
要提取css使用mini-css-extract-plugin
若是但願用npm start
命令構建能夠在package.json
的scripts
中配置。 目前還沒區分開發和生產環境就能夠簡單一點 "start": "webpack --config build/webpack.base.conf.js"
就行
以上配置好了先不急着區分開發環境和生產環境,先加點文件測試打包是不是預期想要的結果,成功後再來區分配置
我使用的是webpack-dev-server
來啓動一個本地開發服務。對於webpack-dev-server
的配置webpack官網有詳細的講解。我就很少說了,本身看着配!
地址:www.webpackjs.com/configurati…
對於其餘插件的配置,好比熱更新
什麼的很簡單的,就不說了
此外我但願個人開發環境的terminal也能像vue-cli那樣打印啓動的地址、編譯進度等。具體能夠看看我本身配置的【手動滑稽】。
效果圖以下:
生產環境就是要對文件進行壓縮、打包。有css壓縮,js壓縮,js提取,sourceMap等。這些固然要配合一些插件來進行。我也很少說了,本身動手豐衣足食!順即可以參照我配置的【手動狗頭】。
開發環境和生產環境區分了,要記得從新配置一下package.json文件啦~
如下是個人配置
"scripts": {
"dev": "set NODE_ENV=development && webpack-dev-server --config build/webpack.dev.conf.js",
"build": "set NODE_ENV=production && webpack --config build/webpack.prod.conf.js"
}
複製代碼
除此以外你還能夠建一個config.js
文件用於方便修改一些配置,好比開發環境啓動端口,地址,代理配置,是否須要啓用sourceMap等等。
到這裏就結束啦。想要擴展的後續還能夠集成一些測試環境。寫的很差不要介意,不足之處還望多多指教。感謝~
PS:一個遺留問題:我但願經過端檢測,在開發環境啓動前判斷配置的端口是否佔用,佔用則用新端口,即:上一個端口 + 1。然而個人並無成功o(╥﹏╥)o。但願有大佬能夠指點一下
如下是端口檢測代碼
function portIsOccupied (port) {
const net = require('net')
const server = net.createServer().listen(port)
let noOccPort = port
server.on('listening',() => {
noOccPort = port
server.close()
})
server.on('error',(err)=>{
if (err.code === 'EADDRINUSE') {
console.log(`${port}端口已被佔用,自動啓用端口:${port + 1}`)
portIsOccupied(port + 1)
}
})
return noOccPort
}
複製代碼