成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

從零開始:一個(gè)正式的vue+webpack項(xiàng)目的目錄結(jié)構(gòu)是怎么形成的

liangdas / 1440人閱讀

摘要:一個(gè)持續(xù)可發(fā)展,不斷加入新功能,方便后期維護(hù)的目錄結(jié)構(gòu)究竟是長(zhǎng)什么樣子的接下來(lái)閏土大叔帶你們一起手摸手學(xué)起來(lái)。

如何從零開始一個(gè)vue+webpack前端工程工作流的搭建,首先我們先從項(xiàng)目的目錄結(jié)構(gòu)入手。一個(gè)持續(xù)可發(fā)展,不斷加入新功能,方便后期維護(hù)的目錄結(jié)構(gòu)究竟是長(zhǎng)什么樣子的?接下來(lái)閏土大叔帶你們一起手摸手學(xué)起來(lái)。

初級(jí)前端初始化目錄篇

項(xiàng)目伊始,我們肯定是先在terminal終端命令行(以下簡(jiǎn)稱terminal)cd進(jìn)入根目錄,然后輸入 npm init 初始化一個(gè)npm項(xiàng)目,在項(xiàng)目根目錄下面就會(huì)出現(xiàn)一個(gè)package.json文件。
然后就可以安裝依賴了,直接在terminal里輸入 npm i webpack vue vue-loader -D。當(dāng)我們把這幾個(gè)安裝好以后,terminal這邊會(huì)提示我們WARN(警告??):

翻譯過來(lái)大意是,vue-loader需要一個(gè)css-loader和vue-template-compiler作為它的第三方依賴,所以聽它的話,我們?nèi)ミM(jìn)行一下安裝:

npm i css-loader vue-template-compiler -D

那下面的警告信息提示我們?nèi)鄙僖恍┬畔?,這個(gè)其實(shí)無(wú)關(guān)痛癢,所以不需要去關(guān)心它。

通過以上簡(jiǎn)單幾個(gè)步驟,我們的項(xiàng)目就初始化好了。然后在根目錄下面創(chuàng)建一個(gè)src文件夾,這是我們?cè)创a放置的目錄。然后我們?cè)趕rc目錄下面新建一個(gè)app.vue文件,里面就可以寫一些關(guān)于項(xiàng)目的業(yè)務(wù)代碼:



當(dāng)然這個(gè)后綴為.vue 文件是不可以在瀏覽器里直接運(yùn)行的,我們需要想辦法讓它運(yùn)行起來(lái)。

現(xiàn)在我們要在項(xiàng)目根目錄下新建一個(gè)webpack.config.js文件,webpack是幫我們前端來(lái)打包資源的,前端資源有很多不同的類型,比如說(shuō)JavaScript,css,html,image,iconfont等這些資源都是需要通過http請(qǐng)求加載的東西。webpack是將一個(gè)js文件加載到瀏覽器端之后,然后去把所有的內(nèi)容去渲染出來(lái)。所以,很多時(shí)候,我們可以把js文件作為項(xiàng)目的入口文件。

這個(gè)時(shí)候,我們?cè)趕rc目錄下新建一個(gè)index.js作為入口文件,順便在里面寫點(diǎn)東西:

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準(zhǔn)備完畢之后,那么在webpack.config.js里面就可以這樣寫:

const path = require("path")

module.exports = {
    entry:  path.join(__dirname, "src/index.js"),
    output: {
        filename: "bundle.js",
        path: path.join(__dirname, "dist")
    }
}

在上面的代碼中,__dirname就代表這個(gè)文件所在的目錄地址,path.join()的意思就是和后面的字符串路徑拼接起來(lái),形成一個(gè)絕對(duì)的路徑。

然后通過webpack把所有的文件打包成一個(gè)bundle.js文件,并且是能在瀏覽器里面直接運(yùn)行的代碼?,F(xiàn)在我們可以在package.json 文件里的scripts對(duì)象里面添加一個(gè)腳本:

"scripts": {
    "build": "webpack --config webpack.config.js"
}

看到這兒,肯定有童鞋要問了,為什么要在這里面調(diào)用webpack而不是在terminal里面直接運(yùn)行呢?

因?yàn)橹挥性谶@里調(diào)用webpack,它才會(huì)優(yōu)先調(diào)用我們項(xiàng)目里面安裝的webpack版本,如果我們?cè)诿钚欣锩孑斎雡ebpack,它會(huì)調(diào)動(dòng)全局的webpack,這個(gè)時(shí)候全局的webpack可能會(huì)跟我們項(xiàng)目中的webpack版本不一致,所以我們還是采取這種方式比較穩(wěn)妥。

寫完之后,我們就可以在terminal輸入 npm run build 跑一下,會(huì)尷尬地發(fā)現(xiàn)報(bào)錯(cuò)了:

這個(gè)錯(cuò)誤告訴我們,需要為.vue文件去聲明一個(gè)loader。因?yàn)閣ebpack原生是只支持JS文件類型的,并且只支持ES5的語(yǔ)法,所以我們?cè)谑褂贸鏊斫夥秶恼Z(yǔ)法的時(shí)候,我們要使用一些幫它去處理的工具。所以我們要在webpack.config.js文件里面繼續(xù)寫:

module: {
    rules: [
        {
            test: /.vue$/,
            loader: "vue-loader"
        }
    ]
}

添加完這段之后,我們?cè)偃erminal執(zhí)行下npm run build,你會(huì)發(fā)現(xiàn)項(xiàng)目根目錄下多了一個(gè)dist文件夾,點(diǎn)開里面發(fā)現(xiàn)webpack為我們自動(dòng)打包生成了一個(gè)bundle.js文件,感興趣的童鞋可以點(diǎn)開這個(gè)js文件看看:

它里面代碼很多,上面是固有的webpack的代碼,這些代碼是處理項(xiàng)目中的模塊依賴的,因?yàn)槲覀冺?xiàng)目里有很多的js相互依賴。

往下翻到100多行左右的時(shí)候,你會(huì)發(fā)現(xiàn)有很多的代碼其實(shí)是vue源碼。因?yàn)槲覀冺?xiàng)目要依賴vue.js,所以webpack會(huì)把vue.js文件打包進(jìn)來(lái)。

你可以通過快捷鍵 command (Ctrl) + F 查找關(guān)鍵詞$mount看到,紅線圈住的這段代碼就是我們自己寫的代碼,其實(shí)webpack做的工作就是把這些不同的靜態(tài)資源的類型打包成一個(gè)js,然后我們?cè)趆tml里面引用這個(gè)js,就可以正常運(yùn)行。

相信大家做前端都知道,在做一個(gè)項(xiàng)目開發(fā)的時(shí)候,我們希望把一些零碎的js文件打包到一起,這樣可以減少http請(qǐng)求。同樣的,我們希望使用模塊依賴,因?yàn)轫?xiàng)目中會(huì)做很多可復(fù)用的代碼,把它寫到一個(gè)模塊里面去,這樣的話當(dāng)我們?cè)偃懸粋€(gè)新項(xiàng)目的時(shí)候,不用再把原來(lái)的代碼重新寫一遍,或者是拷貝一份。

當(dāng)然這里面我們暫時(shí)沒有提到.babelrc、.eslintrc、editorconfig、postcss.config.js等,這些我們留到后面再講。

中級(jí)前端合理細(xì)化目錄篇

初始化工作完成之后,接下來(lái)我們要細(xì)分目錄了。首先我們需要在項(xiàng)目的根目錄下新建一個(gè)文件夾叫build,把webpack的文件多帶帶放到這個(gè)文件夾里面。因?yàn)槲覀冺?xiàng)目中會(huì)用到很多不同的相關(guān)文件的配置,接下來(lái)先新建一個(gè) webpack.config.base.js 文件,我們把webpack里面需要用到的共同的配置放到這個(gè)base的文件里面。比如開發(fā)環(huán)境和正式環(huán)境,以及后期我們要提到的服務(wù)端渲染的環(huán)境。我們都依賴于base這個(gè)配置。

以下是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

然后我們?cè)傩陆ㄒ粋€(gè) webpack.config.client.js ,這個(gè)client文件依賴于base文件,在此基礎(chǔ)上擴(kuò)展一些其他配置。因此我們需要在webpack.config.client.js里面敲入一行代碼引入base文件 :

const baseConfig = require("./webpack.config.base")

基礎(chǔ)工作做完之后,我們?cè)撊绾稳U(kuò)展配置呢?首先在terminal終端命令行安裝下 npm i webpack-merge -D 我們需要webpack-merge這個(gè)工具幫助去擴(kuò)展、合并不同的webpack配置,然后根據(jù)聲明好的isDev來(lái)判斷應(yīng)該怎么合并配置。

以下是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) {
  // 開發(fā)環(huán)境的配置
  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 {
  // 正式環(huán)境的配置
  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

最后,這個(gè)src文件夾我們要重命名一下,叫client,因?yàn)槲覀兒笃谶€要寫服務(wù)端的代碼,對(duì)應(yīng)的就命名成server,正好對(duì)應(yīng)它的含義。這樣看起來(lái),名稱就變得更加的合理。

當(dāng)我們?nèi)f事大吉的時(shí)候,千萬(wàn)記得要把 webpack.config.base.js 和 webpack.config.client.js 里面的src路徑改掉,換成client,否則就會(huì)報(bào)錯(cuò)。

以上就是我們項(xiàng)目最終形成的目錄結(jié)構(gòu),client目錄下分別有assets、layout、views這三個(gè)文件夾,其中assets目錄下放靜態(tài)資源,例如images、styles等;layout目錄下放通用布局的組件;views目錄下放具體的業(yè)務(wù)代碼的組件。

當(dāng)然,這個(gè)目錄其實(shí)還可以隨著項(xiàng)目的開發(fā)再細(xì)分下去,這里就不展開敘述了。

寫在最后

大家一定要注意,在我們正式開發(fā)項(xiàng)目、創(chuàng)建一個(gè)項(xiàng)目工程的時(shí)候,一定要先把目錄結(jié)構(gòu)理順,條理一定要清楚。每個(gè)目錄結(jié)構(gòu)里面放什么東西,心里一定要先有個(gè)概念。以后新建的文件不要亂放,因?yàn)轫?xiàng)目一旦做大,維護(hù)時(shí)間比較久的時(shí)候,可能兩三個(gè)月里面都有一個(gè)文件你不會(huì)去碰它。到時(shí)候如果要去找一個(gè)東西的時(shí)候,你會(huì)找不到它,這是非常令人難受的一件事情。

最重要的一點(diǎn)是,目錄結(jié)構(gòu)的混亂,會(huì)導(dǎo)致你后續(xù)開發(fā)項(xiàng)目的效率變得非常的低。

這次關(guān)于“一個(gè)正式項(xiàng)目的目錄結(jié)構(gòu)是怎么形成的”的話題就說(shuō)到這里,我之后的文章會(huì)講些什么呢?文章預(yù)告如下:

eslint的錯(cuò)誤修復(fù)小技巧

vue-loader是如何配置的

如何回答“對(duì)vue生命周期的理解”才能讓面試官滿意?

淺談css-module的配置

......

正式環(huán)境打包以及異步模塊打包優(yōu)化

以上內(nèi)容均會(huì)第一時(shí)間發(fā)布在我的公眾號(hào):閏土大叔 ,歡迎關(guān)注。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94168.html

相關(guān)文章

  • 為什么我不推薦你使用vue-cli創(chuàng)建腳手架?

    摘要:后來(lái)經(jīng)過排查你會(huì)發(fā)現(xiàn)是由于目前還沒有版本??梢允褂迷摲绞浇鉀Q。這就是我為什么不推薦你使用創(chuàng)建腳手架的原因此文的受眾是想要進(jìn)階中級(jí)的初級(jí)前端人員。 最近在知乎看到一個(gè)問題,原問題如下: 很奇怪,為什么現(xiàn)在能找到自己手動(dòng)創(chuàng)建vue腳手架的文章非常少,而且大家似乎對(duì)webpack4的熱情并不高,對(duì)于想基于vue2.0+webpack4搭建一個(gè)腳手架的我來(lái)說(shuō)資料真是少得可憐。難道現(xiàn)在一般的做...

    trigkit4 評(píng)論0 收藏0
  • 從零開始搭建Vue組件庫(kù)——VV-UI

    摘要:各個(gè)大廠也相繼宣布開源。但是也會(huì)存在一些問題,比如每個(gè)公司可能需要的業(yè)務(wù)組件不盡相同,或者我們想自己開發(fā)一套屬于自己的組件庫(kù),來(lái)增強(qiáng)對(duì)組件的可控性。 前言: 前端組件化是當(dāng)今熱議的話題之一,也是我們?cè)陂_發(fā)單頁(yè)應(yīng)用經(jīng)常會(huì)碰到的一個(gè)問題,現(xiàn)在我們有了功能非常完善的Element-UI。各個(gè)大廠也相繼宣布開源XXX-UI。但是也會(huì)存在一些問題,比如每個(gè)公司可能需要的業(yè)務(wù)組件不盡相同,或者我們...

    BothEyes1993 評(píng)論0 收藏0
  • 從零開始搭建Vue組件庫(kù)——VV-UI

    摘要:各個(gè)大廠也相繼宣布開源。但是也會(huì)存在一些問題,比如每個(gè)公司可能需要的業(yè)務(wù)組件不盡相同,或者我們想自己開發(fā)一套屬于自己的組件庫(kù),來(lái)增強(qiáng)對(duì)組件的可控性。 前言: 前端組件化是當(dāng)今熱議的話題之一,也是我們?cè)陂_發(fā)單頁(yè)應(yīng)用經(jīng)常會(huì)碰到的一個(gè)問題,現(xiàn)在我們有了功能非常完善的Element-UI。各個(gè)大廠也相繼宣布開源XXX-UI。但是也會(huì)存在一些問題,比如每個(gè)公司可能需要的業(yè)務(wù)組件不盡相同,或者我們...

    wthee 評(píng)論0 收藏0
  • 無(wú)痛學(xué)會(huì)各種 2 Vue2+Vuex2+Webpack2 前后端同構(gòu)渲染

    摘要:它會(huì)檢測(cè)出最大靜態(tài)子樹就是不需要?jiǎng)討B(tài)性的子樹并且從渲染函數(shù)中萃取出來(lái)。這樣在每次重渲染的時(shí)候,它就會(huì)直接重用完全相同的同時(shí)跳過比對(duì)。需要注意的是,中的操作必須是同步的,不可以存在異步操作的情況。 新增:哈哈,最近又推出了 vue 的文章,在這里放個(gè)鏈接~手把手教你從零寫一個(gè)簡(jiǎn)單的 VUE 感謝有人看我扯技術(shù),這篇文章主要介紹最近非?;鸬膙ue2前端框架的特點(diǎn)和vue2+vuex2+we...

    fish 評(píng)論0 收藏0
  • 無(wú)痛學(xué)會(huì)各種 2 Vue2+Vuex2+Webpack2 前后端同構(gòu)渲染

    摘要:它會(huì)檢測(cè)出最大靜態(tài)子樹就是不需要?jiǎng)討B(tài)性的子樹并且從渲染函數(shù)中萃取出來(lái)。這樣在每次重渲染的時(shí)候,它就會(huì)直接重用完全相同的同時(shí)跳過比對(duì)。需要注意的是,中的操作必須是同步的,不可以存在異步操作的情況。 新增:哈哈,最近又推出了 vue 的文章,在這里放個(gè)鏈接~手把手教你從零寫一個(gè)簡(jiǎn)單的 VUE 感謝有人看我扯技術(shù),這篇文章主要介紹最近非常火的vue2前端框架的特點(diǎn)和vue2+vuex2+we...

    30e8336b8229 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<