WebPack在多頁應用項目中的探索

WebPack在項目配置中的探索(持續更新中)

  • webpack + gulp + vue (thinkPHP後臺配置)javascript

1、項目需求(請認真看目錄結構,項目構建很大都基於目錄來的)

--- Application
    |--- Home
    |   |--- View (線上用戶訪問的.html目錄)
--- Public (線上資源文件目錄)
    |--- js
    |--- images
    |--- css
    |--- ...
--- source (前端開發目錄)
    |--- index (一個業務需求模塊,每一個業務需求模塊下會有不少頁面)
    |    |--- index (index 頁面)
    |    |      |--- images    
    |    |    |--- index.html 
    |    |    |--- app.vue
    |    |    |--- index.js
    |    |    |--- style.scss
    |    |    |--- ...
    |    |--- topics (topics 頁面)
    |    |    |--- images
    |    |    |--- topics.html
    |      |      |    ...
    |--- crowd (另一個業務需求模塊,每一個業務需求模塊下會有不少頁面)          
    |    |--- index 
    |    |    |--- index.html

以上是咱們的一個項目結構css

  • 1.我所想要的是每個業務需求模塊下(source/index)會有不少頁面html

  • 每個頁面都是一個文件夾(source/index/index,source/index/topics)前端

  • 2.項目無需後臺環境瀏覽器能夠直接打開訪問vue

  • 3.每一個頁面資源如.sass文件,.js文件等就近維護,用.vue + es6的形式進行組件模塊化的開發java

  • 4.開發時擁有良好的sourseMap調試webpack

  • 5.當咱們不須要這個業務模塊,或者某個頁面的時候能夠直接刪除整個文件夾便可git

webpack會幫助咱們會爲每個頁面生成他本身的css文件,js文件. es6

因爲是多頁應用,在這個人html都是手動建立的(還沒找到什麼好的解決辦法),因此咱們直接在咱們的index頁面裏link和script他們github

<link rel="stylesheet" href="../../../Public/css/index/index.css">
    <script src="../../../Public/js/index/index.js"></script>

當咱們須要上線的時候在用gulp把相對路徑給替換成線上路徑

2、webpack

module.exports = {
    entry: {}, //路口
    output: { }, //輸出出口
    module: {
        loaders: [ ]
    },
    babel: { //配置babel
        "presets": ["es2015"],
        "plugins": ["transform-runtime"]
    },
    plugins: [ ],//編譯的時候所執行的插件數組
    vue: { },//vue的配置,須要單獨出來配置
    devtool : "source-map" //調試模式
};

這很簡單就不過多介紹,因爲咱們是多頁應用,咱們須要編寫一個函數獲取全部路口js,生成一個咱們想要的路徑的對象.

3、entry

//須要用到glob模塊
var glob = require('glob');

var getEntry = function () {
    var entry = {};
    //首先咱們先讀取咱們的開發目錄
    glob.sync('./source/**/*.js').forEach(function (name) {
        var n = name.slice(name.lastIndexOf('source/') + 7, name.length - 3);
        n = n.slice(0, n.lastIndexOf('/'));
        //接着我對路徑字符串進行了一些裁剪成想要的路徑
        entry[n] = name;
    });
    
    console.log(entry); 
    /**
    *     entry = { 
    *                'crowd/index' : './source/crowd/index/index.js',
    *                'index/index' : './source/index/index/index.js'
    *               }
    *
    **/
    //最後返回entry  給 webpack的entry
    return entry; 
};

4、output

output: { //輸出位置
    path: path.resolve(__dirname, './public/'), //配置輸出路徑
    filename: './js/[name].js' //文件輸出形式
    //關於filename 咱們有個變量就是 [name] = entry的key  固然還有別的變量好比[id],[hash]等,你們能夠自行發揮
    //咱們也能把filename寫成  filename : [name]/[name].[name].js 也是能夠的
},

5、loader

關於loader,其實有兩種寫法

{
    test: /\.(png|jpg|gif)$/,
    loader: 'url?limit=10000&name=./images/[name].[ext]?[hash:10]',
    /*query: {
        limit: 10000,
        name: './images/[name].[ext]?[hash:8]'
    }*/
},

//在這不管是直接loader 後面跟參數(像url跟參同樣),或者是後面跟着一個對象 query,都是能夠的.

6、 plugins

  • 這裏我就只用到一個就是生成 獨立的css文件,style嵌套在頁面裏的方式實在是醜得不行

7、 vue

這沒啥好說的,vue更新以後須要單獨出來配置了

vue: { //vue的配置,須要單獨出來配置
    loaders: {
        js: 'babel'
    }
}

8、 NODE_ENV

  • 以上都是咱們的開發配置,在生產環境中,咱們還須要添加一些東西

  • 關於調試 在這裏我也處理了很是久,若是開發的時候直接把vue的配置都寫好,那在 頁面是有問題的.因此咱們得另外寫一套vue,專門在生產環境中使用

//因爲咱們的.vue文件模塊化開發,裏面天然也有 css與sass,咱們也須要配置最後導出css文件
var vueLoader = {
    js: 'babel',
    css: ExtractTextPlugin.extract("vue-style-loader", "css-loader"),
    sass: ExtractTextPlugin.extract("vue-style-loader", "css-loader", 'sass-loader')
};

if (process.env.NODE_ENV === 'production') { //判斷是否爲生產環境

    module.exports.vue.loaders = vueLoader;
    //如下直接借鑑尤大大的了
    module.exports.plugins = (module.exports.plugins || []).concat([
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new webpack.optimize.OccurenceOrderPlugin()
    ]);
} else { //不是生產環境則配置devtool 調試
    module.exports.devtool = 'source-map';
}

9、 gulp

  • 僅僅只有webpack部分仍是無法知足咱們的初衷,因此咱們須要gulp進行輔助

webpack僅僅只會把咱們js路口裏的全部東西都處理了,可是咱們的頁面都是咱們本身手動寫的(還沒想到更好的解決方案)

因此咱們須要藉助gulp的力量,把咱們的.html移入咱們想要的目錄

可是這樣的目錄結構輸出實際上是有問題的

--- source (前端開發目錄)
    |--- index (一個業務需求模塊,每一個業務需求模塊下會有不少頁面)
    |    |--- index (index 頁面)
    |    |      |--- images    
    |    |    |--- index.html 
    |    |    |--- app.vue
    |    |    |--- index.js
    |    |    |--- style.scss
    |    |    |--- ...
    |    |--- topics (topics 頁面)
    |    |    |--- images
    |    |    |--- topics.html
    |      |      |    ...
    |--- crowd (另一個業務需求模塊,每一個業務需求模塊下會有不少頁面)          
    |    |--- index 
    |    |    |--- index.html

//咱們能夠知道gulp經過通配符 ./source/**/*.html 匹配到的文件 輸入輸出目錄結構都是相同的

//那咱們就會獲得如下錯誤的輸出結構

--- Application (錯誤結構)
    |--- Home
    |   |--- View (線上用戶訪問的.html目錄)
    |         |--- index (一個業務需求模塊)
    |          |      |--- index (index 頁面,多餘的目錄)
    |         |     |     |--- index.html
    |         |     |--- topics (topics頁面,多餘的目錄)
    |          |     |     |--- topics.html
    |         |--- crowd (crowd業務模塊)
    |         |     |--- index (crowd業務模塊 index頁面,多餘的目錄)
    |         |     |     |--- index.html

//咱們的業務模塊文件應該包含全部的業務頁面,而無需一個頁面就是一個文件夾.
//因此如下才是正確的目錄結構

--- Application (正確結構)
    |--- Home
    |   |--- View (線上用戶訪問的.html目錄)
    |    |    |--- index (一個業務需求模塊)
    |    |    |     |--- index.html
    |    |    |     |--- topics.html
    |    |    |--- crowd (另外一個業務需求模塊)
    |    |    |     |--- index.html
  • 本人想了很是多種方式都沒辦法實現,最後找到了惟一的辦法(很是的愚蠢的辦法,若是您有更好的辦法麻煩告訴我 T.T)

var map = require('map-stream');
var vfs = require('vinyl-fs');

gulp.task('view', function () {

    var log = function(file, cb) { 
        //定義輸出路徑
        var view = __dirname + '/Application/Home/View';
        
        //又是一段切割過程 獲取咱們想要的結構
        var target = file.path.split('/').splice(-3);
        var qqqq = target.splice(1, 1);
        
        //設置咱們的文件輸出path
        file.path = view + '/' + target.join('/'); 
        cb(null, file);
    };
    vfs.src('./source/**/*.html')
        .pipe(rev()) //這裏您能夠作一些pipe的操做
        .pipe(map(log))
        .pipe(vfs.dest('./output')); //這裏會多輸出一次

    gulp.start(['clean']); //咱們須要執行一次clean 清理了多餘的那層目錄
});
  • 這樣咱們就能得到咱們想要的目錄! 而且還能通過pipe對html文件的操做! 最大的難點也就在這裏

以上基本是咱們全部的配置了,關於熱加載,或者是browserSync等別的輔助開發工具,你們能夠在這基礎上自行拓展.

10、後話

年終,前端各類戰爭你們也都看見了.在這樣一個前端需求極速增加,百家爭鳴,百花齊放的黃金時代.你們應該持續保持學習的熱情

關注時代發展,觀望技術發展,不盲目跟風,選擇最適合本身的,最符合現有項目的.

假若一個工具無法爲大家的項目帶來更好的效率,給開發帶來更有益的發展.那你最好保持觀望,別盲從.

本人沒有經歷過grunt時代,可是自從學習前端自動化構建以來也是一路從 grunt -> gulp -> webpack 過渡的

在這期間徹底能夠了解他們以前的差別和不一樣,更多的應該學習思想

你應該多質問本身,爲何這個工具當下會火呢?你應該不該該學習?

我十分不贊同那些拿來即用的同窗,說什麼不久以後就死了,學也沒什麼用,浪費時間,我抄一個不就行了嗎?

雖然我寫得都很基礎,但我仍是但願您別看個人文章.

  • 若是能給您帶來不錯的學習體驗,麻煩請右上角star : ) hava a nice day

原文地址: http://www.meckodo.com/?p=525

所有代碼:https://github.com/MeCKodo/webpack

相關文章
相關標籤/搜索