Gulp & webpack 配置詳解

--

1. Gulp VS webpack 比較

Gulp 是一個任務管理工具,讓簡單的任務更清晰,讓復雜的任務易于掌控;而 webpack 的理念是,一切皆為模塊,每個模塊在打包的時候都會經過一個叫做 loader 的東西,它具備非常強大的精細化管理能力,主要解決的是依賴分析問題。

Gulp:搞清楚 gulp.src, gulp.dest, gulp.task, gulp.watch 四個 API 就差不多了,它的底層原理是使用 Node 的 Transform Streams,這是一個可讀可寫可做中間轉換的 Streams 管道,由于從 src 到 dest 過程中,文件一直停留在 Streams 中,沒有落地成為實體文件,所以整體運作效率非常高。

gulp 常用插件:

  • gulp-load-plugins:自動加載 package.json 中的 gulp 插件
  • gulp-rename: 重命名
  • gulp-uglify:文件壓縮
  • gulp-concat:文件合并
  • gulp-less:編譯 less
  • gulp-sass:編譯 sass
  • gulp-clean-css:壓縮 CSS 文件
  • gulp-htmlmin:壓縮 HTML 文件
  • gulp-babel:使用 babel 編譯 JS 文件
  • gulp-jshint:jshint 檢查
  • gulp-imagemin:壓縮 jpg、png、gif 等圖片
  • gulp-livereload:當代碼變化時,它可以幫我們自動刷新頁面

Webpack 概念很多,但搞清楚 entry,outputloader 三個關鍵點,基本上就可以解決簡單的問題了,稍微復雜的場景主要包括對資源的合并處理、分拆處理、多次打包等,部分這樣的問題可以使用插件輔助解決,但是 Webpack 的強大并不在文件處理,而是依賴分析,所以在流程操作特別復雜的情況,webpack 并不能勝任工作,往往會被作為 gulp 的一個 task,整體工作流交給 gulp 主導。

webpack 常用的 loaderplugin

Loader 列表

  • less-loader, sass-loader:處理樣式
  • url-loader, file-loader:兩個都必須用上。否則超過大小限制的圖片無法生成到目標文件夾中
  • babel-loader,babel-preset-es2015babel-preset-react:js 處理,轉碼
  • expose-loader: 將 js 模塊暴露到全局

Plugin 列表

  • NormalModuleReplacementPlugin:匹配 resourceRegExp,替換為 newResource
  • ContextReplacementPlugin:替換上下文的插件
  • IgnorePlugin:不打包匹配文件
  • PrefetchPlugin:預加載的插件,提高性能
  • ResolverPlugin:替換上下文的插件
  • DedupePlugin:刪除重復或者相似的文件
  • LimitChunkCountPlugin:限制打包文件的個數
  • UglifyJsPlugin:JS文件的壓縮
  • CommonsChunkPlugin:共用模塊提取
  • HotModuleReplacementPlugin:runtime時候的模塊熱替換
  • NoErrorsPlugin:跳過編譯時出錯的代碼并記錄,使編譯后運行時的包不會發生錯誤。
  • HtmlWebpackPlugin:HTML模塊的熱更新

--

2. Gulp 簡介

Gulp.js 是一個自動化構建工具,開發者可以使用它在項目開發過程中自動執行常見任務。Gulp.js 是基于 Node.js 構建的,利用 Node.js 流的威力,你可以快速構建項目并減少頻繁的 IO 操作。Gulp.js 源文件和你用來定義任務的 Gulp 文件都是通過 JavaScript(或者 CoffeeScript )源碼來實現的。

image.png

--

2.1 安裝 Gulp

1 . 全局安裝 gulp

npm install --global gulp

2 . 作為項目的開發依賴(devDependencies)安裝:

npm install --save-dev gulp

我們全局安裝了gulp,項目也安裝了gulp,全局安裝gulp是為了執行gulp任務,本地安裝gulp則是為了調用gulp插件的功能。

2.2 配置Gulp

在項目根目錄下創建一個名為 gulpfile.js 的文件,gulpfile.js是gulp項目的配置文件

var gulp = require('gulp');

gulp.task('default', function() {
  // 將你的默認的任務代碼放在這
});

2.3 運行gulp

在命令提示符執行 gulp 任務名稱

<!-- 調用默認任務default -->
gulp  或者  gulp default

2.4 清除文件

通過gulp刪除某個文件夾的文件

1 . 安裝 gulp-clean

npm i gulp-clean --save-dev

2 . 編寫 gulpfile.js 代碼

var clean = require('gulp-clean');

gulp.task('clean', function() {
    return gulp.src(['dist/css', 'dist/js'], { read: false })
               .pipe(clean());
});

2.5 編譯less

通過gulp編譯LESS代碼

1 . 安裝 gulp-less

npm i gulp-less --save-dev

2 . 編寫 gulpfile.js 代碼

var less = require('gulp-less');

gulp.task('styles', function() {
    return gulp.src('src/less/*.less') //源文件路徑
        .pipe(less()) //less編譯
        .pipe(gulp.dest('dist/css')) //目的路徑
});

2.6 自動前綴

通過gulp處理css的自動前綴

1 . 安裝 gulp-autoprefixer

npm i gulp-autoprefixer --save-dev

2 . 編寫 gulpfile.js 代碼

var autoprefixer = require('gulp-autoprefixer');

gulp.task('styles', function() {
    return gulp.src('src/css/*.css') //源文件路徑
        .pipe(autoprefixer()) //自動前綴
        .pipe(gulp.dest('dist/css')) //目的路徑
});

2.7 base64編碼

通過gulp將css中的圖片轉換成base65編碼

1 . 安裝 gulp-base64

npm i gulp-base64 --save-dev

2 . 編寫 gulpfile.js 代碼

var base64 = require('gulp-base64');

gulp.task('styles', function() {
    return gulp.src('src/css/*.css') //源文件路徑
        .pipe(base64()) //base64編碼
        .pipe(gulp.dest('dist/css')) //目的路徑
});

2.8 css壓縮

通過gulp將css進行壓縮

1 . 安裝 gulp-minify-css

npm i gulp-minify-css --save-dev

2 . 編寫 gulpfile.js 代碼

var cssmin = require('gulp-minify-css');

gulp.task('styles', function() {
    return gulp.src('src/css/*.css') //源文件路徑
        .pipe(cssmin()) //css壓縮
        .pipe(gulp.dest('dist/css')) //目的路徑
});

2.9 排列文件順序

通過gulp將js調整前后順序

1 . 安裝 gulp-order

npm i gulp-order --save-dev

2 . 編寫 gulpfile.js 代碼

var order = require("gulp-order");

gulp.task('scripts', function() {
    return gulp.src('src/js/*.js')  //源文件路徑
        .pipe(order([
            "src/js/config.js",
            "src/js/index.js"
        ]))
        .pipe(gulp.dest('dist/js')) //目的路徑
})

2.10 合并文件

通過gulp將多個文件進行合并

1 . 安裝 gulp-concat

npm i gulp-concat --save-dev

2 . 編寫 gulpfile.js 代碼

var concat = require('gulp-concat');

gulp.task('scripts', function() {
    return gulp.src('src/js/*.js')  //源文件路徑
        .pipe(concat('main.js'))  //合并文件
        .pipe(gulp.dest('dist/js')) //目的路徑
})

2.11 重命名文件

通過gulp將文件名進行更改

1 . 安裝 gulp-rename

npm i gulp-rename --save-dev

2 . 編寫 gulpfile.js 代碼

var rename = require('gulp-rename');

gulp.task('scripts', function() {
    return gulp.src('src/js/*.js')  //源文件路徑
         .pipe(rename({  
              suffix: '.min'
          }))   //修改文件名     
         .pipe(gulp.dest('dist/js')) //目的路徑
})

2.12 JS文件壓縮

通過gulp將js文件進行壓縮

1 . 安裝 gulp-uglify

npm i gulp-uglify --save-dev

2 . 編寫 gulpfile.js 代碼

var rename = require('gulp-rename');

gulp.task('scripts', function() {
    return gulp.src('src/js/*.js')  //源文件路徑
         .pipe(uglify())   //壓縮js
         .pipe(gulp.dest('dist/js')) //目的路徑
})

2.13 圖片壓縮

通過gulp將圖片進行壓縮

1 . 安裝 gulp-imagemin

npm i gulp-imagemin --save-dev

2 . 編寫 gulpfile.js 代碼

gulp.task('images', function() {
    return gulp.src('src/img/*')
        .pipe(cache(imagemin({
            optimizationLevel: 3,
            progressive: true,
            interlaced: true
        })))
        .pipe(gulp.dest('dist/img'))
});

2.14 處理串行任務

定義多個任務的順序執行關系,否則默認情況下,任務會以最大的并發數同時運行。

//清除任務
gulp.task('clean', function() {
    return gulp.src('dist/css', { read: false })
        .pipe(clean());
});

//編譯任務
gulp.task('styles', function() {
    return gulp.src('src/less/*.less') //源文件路徑
        .pipe(less()) //less編譯                       
        .pipe(gulp.dest('dist/css')) //目的路徑
});

//先清空目錄,然后再執行編譯CSS
gulp.task('default', ['clean'], function() {
    gulp.start('styles')
});

2.15 熱加載服務

使用 BrowserSync 服務實現文件變更的實時編譯調試

1 . 安裝 browser-sync

npm i browser-sync --save-dev

2 . 編寫 gulpfile.js 代碼

var browserSync = require('browser-sync').create();

gulp.task('dev', function() {
    //初始化browser-sync服務
    browserSync.init({
        server: {
            baseDir: "./dist"
        }
    });
    
    //檢測less文件是否更改,來調用重新編譯css
    gulp.watch('src/less/*', ['styles']);  

    //如果css文件更改過則刷新服務器
    gulp.watch( ['./dist/sys/css/*'] ).on("change", browserSync.reload)
});

--

3. Webpack 簡介

WebPack可以看做是模塊打包機:把你的項目當做一個整體,通過一個給定的主文件(如:index.js),從這個文件開始分析你的項目結構,找到項目的所有依賴文件,使用loaders處理它們,最后打包為一個瀏覽器可識別的JavaScript文件。

image.png

--

3.1 配置webpack

1 . 新建一個項目文件夾,并且安裝webpack

mkdir webpack-demo && cd webpack-demo
npm init -y
npm install --save-dev webpack

2 . 新建html以及js文件如下

<html>
    <head>
        <title>webpack</title>
    </head>
    <body>
        <div class="g-index"></div>
        
        <script src="dist/bundle.js"></script>
    </body>
</html>
<!-- common.js -->
exports.printmsg = function(msg) {
    console.log(msg);
}

<!-- index.js -->
var lib = require('./common.js')
lib.printmsg('good')

3 . 編譯webpack

webpack src/js/index.js dist/bundle.js

可以看到打包結果如下:

$ webpack src/js/index.js dist/bundle.js
Hash: 39e1d99d27c58dd34eb1
Version: webpack 2.5.1
Time: 81ms
    Asset     Size  Chunks             Chunk Names
bundle.js  2.82 kB       0  [emitted]  main
   [0] ./src/js/common.js 58 bytes {0} [built]
   [1] ./src/js/index.js 50 bytes {0} [built]

項目結構如下:

image.png

--

3.2 編寫配置文件

Webpack擁有很多高級的功能,這些功能其實都可以通過命令行模式實現,但是正如已經提到的,這樣不太方便且容易出錯的,一個更好的辦法是定義一個配置文件,這個配置文件其實也是一個簡單的JavaScript模塊,可以把所有的與構建相關的信息放在里面。下面來說明如何定義一個配置文件:

1 . 在根目錄下面新建 webpack.config.js

var path = require('path');

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

2 . 修改 package.json,添加條目如下

{
  ...
  "scripts": {
    "build": "webpack",
  },
  ...
}

3 . 使用命令行編譯項目

npm run build

--

3.3 調試webpack

開發總是離不開調試,如果可以更加方便的調試當然就能提高開發效率,不過打包后的文件有時候你是不容易找到出錯了的地方對應的源代碼的位置的,Source Maps就是來幫我們解決這個問題的。通過簡單的配置后,Webpack在打包時可以為我們生成的source maps,這為我們提供了一種對應編譯文件和源文件的方法,使得編譯后的代碼可讀性更高,也更容易調試。

devtool選項 配置結果
source-map 在一個單獨的文件中產生一個完整且功能完全的文件。這個文件具有最好的source map,但是它會減慢打包文件的構建速度;
cheap-module-source-map 在一個單獨的文件中生成一個不帶列映射的map,不帶列映射提高項目構建速度,但是也使得瀏覽器開發者工具只能對應到具體的行,不能對應到具體的列(符號),會對調試造成不便;
eval-source-map 使用eval打包源文件模塊,在同一個文件中生成干凈的完整的source map。這個選項可以在不影響構建速度的前提下生成完整的sourcemap,但是對打包后輸出的JS文件的執行具有性能和安全的隱患。不過在開發階段這是一個非常好的選項,但是在生產階段一定不要用這個選項;
cheap-module-eval-source-map 這是在打包文件時最快的生成source map的方法,生成的Source Map 會和打包后的JavaScript文件同行顯示,沒有列映射,和eval-source-map選項具有相似的缺點;

在學習階段以及在小到中性的項目上,eval-source-map 是一個很好的選項,不過記得只在開發階段使用它,繼續上面的例子,進行如下配置

var path = require('path');
module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  devtool: 'eval-source-map'
};

--

3.4 建立本地開發服務器

Webpack提供一個可選的本地開發服務器,這個本地服務器基于node.js構建,可以實現代碼的熱加載功能,可以通過它方便的進行代碼的開發。其構建方法如下:

1 . 安裝 webpack-dev-server

npm install --save-dev webpack-dev-server

2 . 修改配置文件 webpack.config.js

var path = require('path');
module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    devServer: {
        contentBase: "./",
        port: 9000,
        inline: true
    }
};

3 . 修改 package.json,添加條目如下

{
  ...
  "scripts": {
    "dev": "webpack-dev-server",
  },
  ...
}

4 . 輸入 npm run dev 啟動 webpack-dev-server

$ npm run dev                                                                            
                                                                                         
> webpackproj@1.0.0 dev F:\Project\DEMO\webpackdemo                                      
> webpack-dev-server                                                                     
                                                                                         
Project is running at http://localhost:9000/                                             
webpack output is served from /                                                          
Content not from webpack is served from ./                                               
Hash: 1aca755d21fcb2c76314                                                               
Version: webpack 2.5.1                                                                   
Time: 918ms                                                                              
        Asset    Size  Chunks                    Chunk Names                             
    bundle.js  316 kB       0  [emitted]  [big]  main                                    
bundle.js.map  375 kB       0  [emitted]         main                                    
chunk    {0} bundle.js, bundle.js.map (main) 302 kB [entry] [rendered]                   
   [35] (webpack)-dev-server/client?http://localhost:9000 5.68 kB {0} [built]            
   [36] ./src/js/index.js 69 bytes {0} [built]                                           
   [37] ./~/ansi-html/index.js 4.26 kB {0} [built]                                       
   [38] ./~/ansi-regex/index.js 135 bytes {0} [built]                                    
   [40] ./~/events/events.js 8.33 kB {0} [built]                                         
   [41] ./~/html-entities/index.js 231 bytes {0} [built]                                 
   [48] ./~/querystring-es3/index.js 127 bytes {0} [built]                               
   [76] ./~/strip-ansi/index.js 161 bytes {0} [built]                                    
   [78] ./~/url/url.js 23.3 kB {0} [built]                                               
   [79] ./~/url/util.js 314 bytes {0} [built]                                            
   [80] (webpack)-dev-server/client/overlay.js 3.73 kB {0} [built]                       
   [81] (webpack)-dev-server/client/socket.js 897 bytes {0} [built]                      
   [83] (webpack)/hot/emitter.js 77 bytes {0} [built]                                    
   [84] ./src/js/common.js 58 bytes {0} [built]                                          
   [85] multi (webpack)-dev-server/client?http://localhost:9000 ./src/js/index.js 40 byte
s {0} [built]                                                                            
     + 71 hidden modules                                                                 
webpack: Compiled successfully.                                                                                                                                  

--

3.5 配置HTML代碼熱加載

webpack-dev-server 只能監控入口文件(JS/LESS/CSS/IMG)的變化,因此 HTML文件的變化必須依賴插件來進行監控。

1 . 安裝 html-webpack-plugin

npm install html-webpack-plugin --save-dev

2 . 修改配置文件 webpack.config.js, 把 index.html 加入監控

var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    plugins: [
        new HtmlWebpackPlugin({   // html代碼熱加載
            template: './index.html'
        }),
    ],
    devServer: {
        contentBase: "./",
        port: 9000,
        inline: true
    }
};

此時可以取消 html 文件內的 js 引用,因為 html-webpack-plugin 會自動加載編譯完的 js 文件

--

3.6 配置自動打開瀏覽器

通過配置 open-browser-webpack-plugin 可以在webpack編譯完之后自動打開瀏覽器;

1 . 安裝 open-browser-webpack-plugin

npm install open-browser-webpack-plugin --save-dev

2 . 修改配置文件 webpack.config.js

var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin')
var OpenBrowserPlugin = require('open-browser-webpack-plugin');

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    plugins: [
        new HtmlWebpackPlugin({ // html代碼熱加載
            template: './index.html'
        }),
        new OpenBrowserPlugin({ //自動打開瀏覽器
            url: 'http://localhost:9000'
        })
    ],
    devServer: {
        contentBase: "./",
        port: 9000,
        inline: true
    }
};

--

3.7 配置 json 加載器

使用 json 解析器可以將常量數據定義在 json文件中,然后在 js 文件中調用。

1 . 在項目根目錄下面創建 config.json 文件,內容如下

{
    "name": "demo",
    "type": "HTML5"
}

2 . 修改 index.js

var config = require('../../config.json')
var lib = require('./common.js')
lib.printmsg(config.name)

3 . 修改配置文件 webpack.config.js

var path = require('path');

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: { 
        rules: [{
            test: /\.json$/,
            loader: "json-loader"
        }]
    }
};

項目結構如下:

image.png

--

3.8 配置 LESS 編譯

1 . 安裝 less style-loader css-loader less-loader

npm install less style-loader css-loader less-loader --save-dev

2 . 在項目的css目錄下面創建 index.less 文件,內容如下

@charset "utf-8";
@gray-base:  #000;
@gray-light:  lighten(@gray-base, 46.7%); 

.g-index {
    height: 100vh;
    background: @gray-light;
}

3 . 修改 index.js

require('../css/index.less')

var lib = require('./common.js')
lib.printmsg('good')

4 . 修改配置文件 webpack.config.js

var path = require('path');

module.exports = {
    devtool: 'source-map',
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: { 
        rules: [
        {
            test: /\.less$/, // less解析器
            loader: 'style-loader!css-loader!less-loader'
        },]
    }
};

項目結構如下:

image.png

--

3.9 配置 Babel 編譯

1 . 安裝 babel-core babel-loader babel-preset-es2015

 npm install babel-core babel-loader babel-preset-es2015 --save-dev

2 . 修改 common.jsES6 格式

exports.printmsg = (msg) => {
    console.log(msg);
}

3 . 修改配置文件 webpack.config.js

var path = require('path');
module.exports = {
    devtool: 'source-map',
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: { 
        rules: [{
            test: /\.js$/,   //babel解析器
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
                presets: ['es2015']
            }
        }]
    }
};

--

3.10 配置 jQuery 解析器

1 . 安裝 jquery

 npm install jquery --save-dev

2 . 修改 index.js 調用 jquery 函數

require('jquery')

$(init)
function init() {
    var lib = require('./common.js')
    lib.printmsg('good')
}

3 . 修改配置文件 webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
    devtool: 'source-map',
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {   
        rules: [{
            test: /\.js$/,  //babel代碼解析
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
                presets: ['es2015']
            }
        }]
    },
    plugins: [
        new webpack.ProvidePlugin({   //jquery解析器
            $: "jquery",
            jQuery: "jquery",
            "window.jQuery": "jquery"
        })
    ]
};

--

3.11 配置 js 代碼壓縮

1 . 修改配置文件 webpack.config.js, 在 plugin 中添加 webpack.optimize.UglifyJsPlugin 模塊

var path = require('path');
var webpack = require('webpack');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;

module.exports = {
    devtool: 'source-map',
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: { //在配置文件里添加JSON loader
        rules: [{
            test: /\.js$/,   //babel代碼解析
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
                presets: ['es2015']
            }
        }]
    },
    plugins: [
         new uglifyJsPlugin({ //js代碼壓縮
            compress: {
                warnings: false
            }
        })
    ]
};

--

3.12 配置 eslint 語法解析

1 . 安裝 esline

 npm install eslint eslint-loader eslint-friendly-formatter eslint-plugin-html babel-eslint eslint-config-standard eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard --save-dev

2 . 在項目根目錄下添加eslint 配置文件.eslintrc.js

// http://eslint.org/docs/user-guide/configuring
module.exports = {
  root: true,
  parser: 'babel-eslint',
  parserOptions: {
    sourceType: 'module'
  },
  env: {
    browser: true,
  },
  // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
  extends: 'standard',
  // required to lint *.vue files
  plugins: [
    'html'
  ],
  // add your custom rules here
  'rules': {
    // allow paren-less arrow functions
    'arrow-parens': 0,
    "indent": [2, 4],//縮進風格
    'no-undef': 0,
    // allow async-await
    'generator-star-spacing': 0,
    // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
  }
}

3 . 修改配置文件 webpack.config.js

var path = require('path');

module.exports = {
    devtool: 'source-map',
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: { 
        rules: [{
            test: /\.js$/,   //babel代碼解析
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
                presets: ['es2015']
            }
        }, {
            test: /\.js$/, //eslint語法解析
            exclude: /node_modules/,
            loader: 'eslint-loader',
            enforce: 'pre',
            options: {
                formatter: require('eslint-friendly-formatter')
            }
        }]
    }
};

--

3.13 配置圖片壓縮器

1 . 安裝 url-loader

 npm install url-loader --save-dev

2 . 修改 index.less 文件

@charset "utf-8";
@gray-base:  #000;
@gray-light:  lighten(@gray-base, 46.7%); 

.g-index {
    height: 100vh;
    background: @gray-light;
    background: url('../img/small.png') no-repeat;
}

3 . 修改配置文件 webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
    devtool: 'source-map',
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [ {
            test: /\.less$/, // less解析器
            loader: 'style-loader!css-loader!less-loader'
        }, {
            test: /\.(png|jpg)$/, // img壓縮器
            loader: 'url-loader?limit=8192'
        }]
    }

項目結構如下:

image.png

--

3.14 配置公共庫抽取

1 . 安裝 chunk-manifest-webpack-plugin webpack-chunk-hash

 npm install chunk-manifest-webpack-plugin webpack-chunk-hash  --save-dev

3 . 修改配置文件 webpack.config.js

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin')
var WebpackChunkHash = require("webpack-chunk-hash");
var ChunkManifestPlugin = require("chunk-manifest-webpack-plugin");

module.exports = {
    devtool: 'source-map',
    entry: { 
        main: './src/js/index.js',
        vendor: ['jquery']
    },
    output: {
        filename: '[name].[chunkhash].js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [ {
            test: /\.less$/, // less解析器
            loader: 'style-loader!css-loader!less-loader'
        }, {
            test: /\.(png|jpg)$/, // img壓縮器
            loader: 'url-loader?limit=8192'
        }]
    },
    plugins: [
        new HtmlWebpackPlugin({ // html代碼熱加載
            template: './index.html'
        }),
        new webpack.ProvidePlugin({ //jquery解析器
            $: "jquery",
            jQuery: "jquery",
            "window.jQuery": "jquery"
        }),
        new webpack.optimize.CommonsChunkPlugin({  //公共庫抽取
            name: ["vendor", "manifest"], // vendor libs + extracted manifest
            minChunks: Infinity,
        }),
        new webpack.HashedModuleIdsPlugin(),
        new WebpackChunkHash(),
        new ChunkManifestPlugin({
          filename: "chunk-manifest.json",
          manifestVariable: "webpackManifest"
        })
    ]
};

--

3.15 配置模塊分析器

在項目復雜的情況下,為了分析多個模塊的相互依賴以及打包的關系,通常引入模塊打包分析工具,可以清晰的給出每個模塊的依賴關系。

1 . 安裝 webpack-bundle-analyzer

 npm install webpack-bundle-analyzer  --save-dev

2 . 修改配置文件 webpack.config.js

var path = require('path');
var { BundleAnalyzerPlugin }  = require('webpack-bundle-analyzer')

module.exports = {
    devtool: 'source-map',
    entry: { 
        main: './src/js/index.js',
        vendor: ['jquery']
    },
    output: {
        filename: '[name].[chunkhash].js',
        path: path.resolve(__dirname, 'dist')
    },
    plugins: [
        new BundleAnalyzerPlugin()
    ]
};
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,202評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,742評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,297評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,688評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,875評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,438評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,183評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,384評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,612評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,093評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,330評論 2 377

推薦閱讀更多精彩內容

  • 在現在的前端開發中,前后端分離、模塊化開發、版本控制、文件合并與壓縮、mock數據等等一些原本后端的思想開始...
    Charlot閱讀 5,467評論 1 32
  • 前言 眾所周知目前比較火的工具就是gulp和webpack,但webpack和gulp卻有所不同,本人兩者的底層研...
    cduyzh閱讀 1,387評論 0 13
  • 無意中看到zhangwnag大佬分享的webpack教程感覺受益匪淺,特此分享以備自己日后查看,也希望更多的人看到...
    小小字符閱讀 8,217評論 7 35
  • 最近在學習 Webpack,網上大多數入門教程都是基于 Webpack 1.x 版本的,我學習 Webpack 的...
    My_Oh_My閱讀 8,199評論 40 247
  • 中國人的年是要到正月十五方才結束的。隨著爆竹聲一日疏似一日,這年的味道也一日淡于一日。 年幼時常聽母親道:怕...
    紫草茵茵閱讀 265評論 0 1