天天看點

用Laravel+Grunt+Bower管理你的應用

轉自:http://yansu.org/2014/03/10/grunt-bower-and-laravel.html

每個開發者都應該有自己的工具箱

為什麼這麼選擇?

如今開源盛行,從後端的各個類庫,到如今前端的jQuery插件,前端架構等,越來越多優秀的元件可以被我們選擇應用在現有的項目中。随着開源元件的更新疊代,它們互相之間的依賴也越來越複雜。舊的架構對于新的變化總是顯得難以适從,就算為了新的特性改變舊的架構,也會顯的略顯牽強。于是就會有新的架構和工具,在這個時候凸現出來。

每個項目開始的方向是很重要的,良好的開始可以避免之後的各種問題。下面要說的三個工具,就是現有應用開發的一個良好開端。

Laravel

Laravel是一個非常新的PHP架構,借鑒了很多前輩的優秀特性,以PHP5為起點,引入了Composer作為包管理工具,号稱為WEB藝術家創造的PHP架構。

Grunt

基于JavaScript的自動化建構工具,可以将重複的任務,例如壓縮(minification),編譯,單元測試,linting等自動化。

Bower

Web前端開發的包管理工具,解決前端架構間的依賴關系,友善子產品化和重用。

優勢

  1. 使用Laravel可以更好的利用最新版PHP的優勢,排除了一些曆史問題。
  2. 利用Composer可以極大減少"輪子"的數量,優秀的包可以去Packagist找到,這些包幾乎都利用Github來托管,利用Github的issue和request可以輔助提高包的品質。
  3. Bower可以幫助統一管理開源前端庫,如Bootstrap和jQuery等,同樣這些包也在Github上托管。
  4. Grunt幫助粘合前後端的開源元件,将合并編譯壓縮等工作自動化。

安裝使用

前提

有些需要提前安裝的元件這裡不在贅述,請自行Google。

  • Composer
  • Node & npm
  • Grunt
  • Bower

Laravel

有了Composer後安裝一個Laravel項目非常容易

安裝完成後在

myproject

目錄下就生成了laravel的架構結構,入口檔案在

public

中。在

myproject

根目錄下,有一個

composer.json

檔案,這個檔案看起來是這樣的:

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "require": {
        "laravel/framework": "4.1.*"
    },
    //...
}
           

這個檔案可以控制項目的一些依賴關系,我們需要一些元件的時候直接在

require

下添加即可,

composer

會幫我們去查找這個元件所需的依賴包。

接着為了安裝前端架構,我們先來建立幾個公共目錄,在

public

下,建立類似的目錄

.
|-- assets
|   |-- css
|   |-- fonts
|   `-- js
|-- favicon.ico
|-- index.php
|-- packages
`-- robots.txt
           

這裡隻有

assets

目錄是我新建立的

Bower

準備好後端架構以後,可以安裝前端架構了,例如

Bootstrap

。利用

Bower

安裝的前端庫是其整個工程,并不是我們需要的個别檔案,是以可以講它們先放在一個位置,之後利用

Grunt

來統一處理。

首先配置一下安裝路徑,在

myproject

根目錄下配置檔案

.bowerrc

{
  "directory": "public/assets/bower"
}
           

這個檔案告訴bower,将下載下傳的包都安裝到

public/assets/bower

下。

接着在根目錄建立一個

bower

的配置檔案

bower.json

{
  "name": "myproject"
}
           

接着添加前端庫

這個指令将會利用配置檔案管理整個庫依賴,這個時候再看一下配置檔案,bower已經幫助我們自動安裝好了

Bootstrap

依賴的包--

jQuery

,同時修改了配置檔案

{
  "name": "myproject",
  "dependencies": {
    "bootstrap": "~3.1.1"
  }
}
           

在看一下目标目錄,

public/assets

下,生成了一個bower目錄,其中包含了

Bootstrap

jQuery

Grunt

根據上面的步驟,我們很友善的建立了後端架構和前端架構,但是前端架構在使用的時候直接用

bower

下的檔案并不是非常友善,而且還可能會涉及到一些庫的合并壓縮等步驟。這些問題都可以交給

Grunt

去做.

首先在

myproject

根目錄下利用

npm init

初始化一個配置檔案。根據提示一步一步填寫即可,最後生成的配置檔案

package.json

應該如下所示:

{
  "name": "myproject",
  "version": "0.0.1",
  "description": "",
  "main": "Gruntfile.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
           

有不一樣的地方不用擔心,盡管修改即可。

接着我們要安裝一些Grunt的插件,幫助我們更好的完成所需功能。

npm install grunt --save-dev
npm install grunt-contrib-concat --save-dev
npm install grunt-contrib-less --save-dev
npm install grunt-contrib-uglify --save-dev
npm install grunt-contrib-watch --save-dev
npm install grunt-contrib-copy --save-dev
npm install grunt-contrib-cssmin --save-dev
           

這裡的每個插件我會在下面的配置中介紹。上面指令中的

--save-dev

選項的作用是将安裝的這些包放入配置檔案依賴項中,友善以後安裝。下面是安裝後的配置檔案:

{
  "name": "myproject",
  "version": "0.0.1",
  "description": "",
  "main": "Gruntfile.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "grunt": "~0.4.3",
    "grunt-contrib-concat": "~0.3.0",
    "grunt-contrib-less": "~0.10.0",
    "grunt-contrib-uglify": "~0.4.0",
    "grunt-contrib-watch": "~0.5.3",
    "grunt-contrib-cssmin": "~0.9.0"
    "grunt-contrib-copy": "~0.5.0"
  }
}
           

注意在安裝後有了一個

node_modules

目錄,這個是node項目依賴包的位置,我們一般都在本地進行檔案的合并和壓縮,是以可以将這個包保留在本地。另外對于

bower

生成的目錄,在

Grunt

處理過以後也是可以不上傳到正式環境中的。是以修改

.gitignore

檔案,将這兩個檔案夾排除出去:

/bootstrap/compiled.php
/vendor
composer.phar
composer.lock
.env.local.php
.env.php
.DS_Store
Thumbs.db
/public/assets/bower
/node_modules
           

接下來就要進行

Grunt

的配置項編寫了,我會在配置中加入注釋幫助了解。還記得我們剛剛建立的

package.json

配置檔案中的入口檔案嗎?這個檔案還不存在,是以我們需要手動建立,在

myproject

下建立

Gruntfile.js

的檔案,内容如下:

module.exports = function(grunt) {
  //配置項
  grunt.initConfig({
    //concat插件配置,用來合并多個檔案
    concat: {
      //檔案間的分隔符
      options: {
        separator: ';',
      },
      //app是一個任務名,可以随意命名
      app: {
        //将進行的合并項
        src: [
          './public/assets/bower/jquery/dist/jquery.js',
          './public/assets/bower/bootstrap/dist/js/bootstrap.js',
        ],
        //合并後放置在
        dest: './public/assets/js/javascript.js',
      },
    },
    //css合并壓縮
    cssmin: {
      //任務名
      app: {
        src: [
          './public/assets/bower/bootstrap/dist/css/bootstrap.css',
          './public/assets/css/base.css'
        ],
        dest: './public/assets/css/stylesheet.css'
      }
    },
    //js壓縮
    uglify: {
      options: {
        mangle: false //是否混合變量,如果需求的話置為true
      },
      app: {
        files: {
          './public/assets/js/javascript.js': './public/assets/js/javascript.js',
        }
      },
    },
    //移動檔案
    copy: {
      app: {
        files: [
          {
            expand: true,
            flatten: true,
            cwd: './public/assets/bower/bootstrap/fonts/',
            src: ['**'], 
            dest: './public/assets/fonts/', 
            filter: 'isFile'
          },
        ]
      }
    },
    //監聽檔案變化,如果檔案變化,将重新進行任務
    watch: {
      app: {
        files: [
          './public/assets/bower/jquery/dist/jquery.js',
          './public/assets/bower/bootstrap/dist/js/bootstrap.js',
          './public/assets/bower/bootstrap/dist/css/bootstrap.css',
        ],   
        //檔案變化後執行哪些任務
        tasks: ['concat:app','uglify:app','cssmin:app','copy:app'],
        options: {
          livereload: true
        }
      },
    }
  });

  //導入所需的插件
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-cssmin');

  //注冊兩個任務
  grunt.registerTask('watch', ['watch']);
  grunt.registerTask('default', ['concat:app','uglify:app','cssmin:app','copy:app']);
};
           

我們看到,最後注冊了兩個任務,這兩個任務可以從終端中執行,例如:

可以開啟檔案監聽,當檔案變化時執行watch中設定的任務。

如果直接執行

grunt

,則會執行

default

中設定的任務。我們也可以具體指定執行某一單一任務,如

上面則隻将

bootstrap/fonts

中的檔案拷貝到

public/assets/fonts

中。

對于上述的這些插件,可以在這裡找到,也有詳細的用法。

總結

每個人都有自己的喜好,我的這種配置可能隻抛個磚,希望有更好的方式分享。最後在總結一下這三劍客:

  • Laravel利用了最新PHP特性,引入了Composer包管理,解決後端庫之間的依賴
  • Bower幫助安裝和解決前端架構和庫的依賴關系
  • Grunt幫助粘合前後端的開源元件,并且完成合并和壓縮等重複性工作。

下面兩篇參考文章各有特色,如果希望了解一下可以點選連結去看。

我在Github上建立了這篇部落格中所講的目錄結構,想要快速建立一個可使用的工程,隻需要以下幾部:

git clone https://github.com/suyan/Laravel-Bower-Grunt.git
composer install
bower update
npm install
grunt
           

Enjoy it!

參考

  1. How I use Bower and Grunt with my Laravel projects
  2. Using Grunt + Bower with Laravel and Bootstrap