如何從零開始一個vue+webpack前端工程工做流的搭建,首先咱們先從項目的目錄結構入手。一個持續可發展,不斷加入新功能,方便後期維護的目錄結構到底是長什麼樣子的?接下來閏土大叔帶大家一塊兒手摸手學起來。css
項目伊始,咱們確定是先在terminal終端命令行(如下簡稱terminal)cd進入<project name>根目錄,而後輸入 npm init
初始化一個npm項目,在項目根目錄下面就會出現一個package.json文件。 而後就能夠安裝依賴了,直接在terminal裏輸入 npm i webpack vue vue-loader -D
。當咱們把這幾個安裝好之後,terminal這邊會提示咱們WARN(警告⚠️):html
翻譯過來大意是,vue-loader須要一個css-loader和vue-template-compiler做爲它的第三方依賴,因此聽它的話,咱們去進行一下安裝:前端
npm i css-loader vue-template-compiler -D
vue
那下面的警告信息提示咱們缺乏一些信息,這個其實無關痛癢,因此不須要去關心它。node
經過以上簡單幾個步驟,咱們的項目就初始化好了。而後在根目錄下面建立一個src文件夾,這是咱們源碼放置的目錄。而後咱們在src目錄下面新建一個app.vue文件,裏面就能夠寫一些關於項目的業務代碼:webpack
<template>
<div id="test">{{text}}</div>
</template>
<script>
export default {
data () {
text: '閏土大叔'
}
}
</script>
<style>
#test{
font-size:12px;
color:green;
}
</style>
複製代碼
固然這個後綴爲.vue 文件是不能夠在瀏覽器裏直接運行的,咱們須要想辦法讓它運行起來。web
如今咱們要在項目根目錄下新建一個webpack.config.js文件,webpack是幫咱們前端來打包資源的,前端資源有不少不一樣的類型,好比說JavaScript,css,html,image,iconfont等這些資源都是須要經過http請求加載的東西。webpack是將一個js文件加載到瀏覽器端以後,而後去把全部的內容去渲染出來。因此,不少時候,咱們能夠把js文件做爲項目的入口文件。面試
這個時候,咱們在src目錄下新建一個index.js做爲入口文件,順便在裏面寫點東西:npm
import Vue from 'vue'
import App from './app.vue'
const root = document.createElement('div')
document.body.appendChild(root)
new Vue({
render: (h) => h(App)
}).$mount(root)
複製代碼
index.js準備完畢以後,那麼在webpack.config.js裏面就能夠這樣寫:json
const path = require('path')
module.exports = {
entry: path.join(__dirname, 'src/index.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
}
}
複製代碼
在上面的代碼中,__dirname就表明這個文件所在的目錄地址,path.join()的意思就是和後面的字符串路徑拼接起來,造成一個絕對的路徑。
而後經過webpack把全部的文件打包成一個bundle.js文件,而且是能在瀏覽器裏面直接運行的代碼。如今咱們能夠在package.json 文件裏的scripts對象裏面添加一個腳本:
"scripts": {
"build": "webpack --config webpack.config.js"
}
複製代碼
看到這兒,確定有童鞋要問了,爲何要在這裏面調用webpack而不是在terminal裏面直接運行呢?
由於只有在這裏調用webpack,它纔會優先調用咱們項目裏面安裝的webpack版本,若是咱們在命令行裏面輸入webpack,它會調動全局的webpack,這個時候全局的webpack可能會跟咱們項目中的webpack版本不一致,因此咱們仍是採起這種方式比較穩妥。
寫完以後,咱們就能夠在terminal輸入npm run build
跑一下,會尷尬地發現報錯了:
這個錯誤告訴咱們,須要爲.vue文件去聲明一個loader。由於webpack原生是隻支持JS文件類型的,而且只支持ES5的語法,因此咱們在使用超出它理解範圍的語法的時候,咱們要使用一些幫它去處理的工具。因此咱們要在webpack.config.js文件裏面繼續寫:
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader'
}
]
}
複製代碼
添加完這段以後,咱們再去terminal執行下npm run build
,你會發現項目根目錄下多了一個dist文件夾,點開裏面發現webpack爲咱們自動打包生成了一個bundle.js文件,感興趣的童鞋能夠點開這個js文件看看:
往下翻到100多行左右的時候,你會發現有不少的代碼實際上是vue源碼。由於咱們項目要依賴vue.js,因此webpack會把vue.js文件打包進來。
你能夠經過快捷鍵 command (Ctrl) + F 查找關鍵詞$mount看到,紅線圈住的這段代碼就是咱們本身寫的代碼,其實webpack作的工做就是把這些不一樣的靜態資源的類型打包成一個js,而後咱們在html裏面引用這個js,就能夠正常運行。
相信你們作前端都知道,在作一個項目開發的時候,咱們但願把一些零碎的js文件打包到一塊兒,這樣能夠減小http請求。一樣的,咱們但願使用模塊依賴,由於項目中會作不少可複用的代碼,把它寫到一個模塊裏面去,這樣的話當咱們再去寫一個新項目的時候,不用再把原來的代碼從新寫一遍,或者是拷貝一份。
固然這裏面咱們暫時沒有提到.babelrc、.eslintrc、editorconfig、postcss.config.js等,這些咱們留到後面再講。
初始化工做完成以後,接下來咱們要細分目錄了。首先咱們須要在項目的根目錄下新建一個文件夾叫build,把webpack的文件單獨放到這個文件夾裏面。由於咱們項目中會用到不少不一樣的相關文件的配置,接下來先新建一個 webpack.config.base.js 文件,咱們把webpack裏面須要用到的共同的配置放到這個base的文件裏面。好比開發環境和正式環境,以及後期咱們要提到的服務端渲染的環境。咱們都依賴於base這個配置。
如下是webpack.config.base.js文件裏的代碼:
const path = require('path')
const createVueLoaderOptions = require('./vue-loader.config')
const isDev = process.env.NODE_ENV === 'development'
const config = {
target: 'web',
entry: path.join(__dirname, '../client/index.js'),
output: {
filename: 'bundle.[hash:8].js',
path: path.join(__dirname, '../dist')
},
module: {
rules: [
{
test: /\.(vue|js|jsx)$/,
loader: 'eslint-loader',
exclude: /node_modules/,
enforce: 'pre'
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: createVueLoaderOptions(isDev)
},
{
test: /\.jsx$/,
loader: 'babel-loader'
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(gif|jpg|jpeg|png|svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024,
name: 'resources/[path][name].[hash:8].[ext]'
}
}
]
}
]
}
}
module.exports = config
複製代碼
而後咱們再新建一個 webpack.config.client.js ,這個client文件依賴於base文件,在此基礎上擴展一些其餘配置。所以咱們須要在webpack.config.client.js裏面敲入一行代碼引入base文件 :
const baseConfig = require('./webpack.config.base')
基礎工做作完以後,咱們該如何去擴展配置呢?首先在terminal終端命令行安裝下 npm i webpack-merge -D
咱們須要webpack-merge這個工具幫助去擴展、合併不一樣的webpack配置,而後根據聲明好的isDev來判斷應該怎麼合併配置。
如下是webpack.config.client.js文件裏的代碼:
const path = require('path')
const HTMLPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
const merge = require('webpack-merge')
const ExtractPlugin = require('extract-text-webpack-plugin')
const baseConfig = require('./webpack.config.base')
const isDev = process.env.NODE_ENV === 'development'
const defaultPlugins = [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: isDev ? '"development"' : '"production"'
}
}),
new HTMLPlugin()
]
const devServer = {
port: 8000,
host: '0.0.0.0',
overlay: {
errors: true
},
hot: true
}
let config
if (isDev) {
// 開發環境的配置
config = merge(baseConfig, {
devtool: '#cheap-module-eval-source-map',
module: {
rules: [
{
test: /\.styl/,
use: [
'vue-style-loader',
'css-loader',
// {
// loader: 'css-loader',
// options: {
// module: true,
// localIdentName: isDev ? '[path]-[name]-[hash:base64:5]' : '[hash:base64:5]'
// }
// },
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
'stylus-loader'
]
}
]
},
devServer,
plugins: defaultPlugins.concat([
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
])
})
} else {
// 正式環境的配置
config = merge(baseConfig, {
entry: {
app: path.join(__dirname, '../client/index.js'),
vendor: ['vue']
},
output: {
filename: '[name].[chunkhash:8].js'
},
module: {
rules: [
{
test: /\.styl/,
use: ExtractPlugin.extract({
fallback: 'vue-style-loader',
use: [
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
'stylus-loader'
]
})
}
]
},
plugins: defaultPlugins.concat([
new ExtractPlugin('styles.[contentHash:8].css'),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor'
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'runtime'
})
])
})
}
module.exports = config
複製代碼
最後,這個src文件夾咱們要重命名一下,叫client,由於咱們後期還要寫服務端的代碼,對應的就命名成server,正好對應它的含義。這樣看起來,名稱就變得更加的合理。
當咱們萬事大吉的時候,千萬記得要把 webpack.config.base.js 和 webpack.config.client.js 裏面的src路徑改掉,換成client,不然就會報錯。
以上就是咱們項目最終造成的目錄結構,client目錄下分別有assets、layout、views這三個文件夾,其中assets目錄下放靜態資源,例如images、styles等;layout目錄下放通用佈局的組件;views目錄下放具體的業務代碼的組件。
固然,這個目錄其實還能夠隨着項目的開發再細分下去,這裏就不展開敘述了。
你們必定要注意,在咱們正式開發項目、建立一個項目工程的時候,必定要先把目錄結構理順,條理必定要清楚。每一個目錄結構裏面放什麼東西,內心必定要先有個概念。之後新建的文件不要亂放,由於項目一旦作大,維護時間比較久的時候,可能兩三個月裏面都有一個文件你不會去碰它。到時候若是要去找一個東西的時候,你會找不到它,這是很是使人難受的一件事情。
最重要的一點是,目錄結構的混亂,會致使你後續開發項目的效率變得很是的低。
此次關於「一個正式項目的目錄結構是怎麼造成的」的話題就說到這裏,我以後的文章會講些什麼呢?文章預告以下: