webpack入門和實戰(二):全面理解和運用loader和plugins

您的閱讀目錄:
1、理解webpack加載器loader
1.一、什麼是loader?
webpack的設計理念,全部資源都是「模塊」,webpack內部實現了一套資源加載機制。loaders 用於轉換應用程序的資源文件,他們是運行在nodejs下的函數 使用參數來獲取一個資源的來源而且返回一個新的來源(資源的位置),例如你可使用loader加載器能夠快速編譯預處理器(less,sass,coffeeScript)。
1.二、使用loader
  • 安裝loader
$ npm install xxx-loader --save-dev
加載器包括:style-loader、css-loader、less-loader、sass-loader、jsx-loader、url-loader、babel-loader、file-loader等等;各個加載器都有本身的功能,你能夠根據項目須要來安裝相應的加載器;
  • 配置loader

安裝完各個loader後,咱們就須要配置一下咱們的webpack.config.js,載入咱們的loader。javascript

// webpack.config.js
module.exports = {
    entry: path.join(__dirname, 'src/entry.js'),
    output: {
        path: path.join(__dirname, 'out'),
        publicPath: "./out/",
        filename: 'bundle.js'
    },
    // 新添加的module屬性
    module: {
        loaders: [
            {test: /\.js$/, loader: "babel"},
            {test: /\.css$/, loader: "style!css"},
            {test: /\.(jpg|png)$/, loader: "url?limit=8192"},
            {test: /\.scss$/, loader: "style!css!sass"}
        ]
    }
};

咱們主要看看module的loaders。loaders是一個數組,裏面的每個對象都用正則表達式,對應着一種配對方案。Webpack提供了一套加載器,好比css-loader,less-loader,style-loader,url-loader等,用於將不一樣的文件加載到js文件中,好比url-loader用於在js中加載png/jpg格式的圖片文件;css/style loader用於加載css文件;less-loader加載器是將less編譯成css文件;不一樣的處理器經過!分隔並串聯起來。這裏的loader是能夠省略掉-loader這樣的,也就是本來應該寫成style-loader!css-loader!sass-loader.css

2、理解less-loader加載器的使用
咱們先來理解下less-loader加載器,其餘的sass-loader也是一個意思,less-loader加載器是把css代碼轉化到style標籤內,動態插入到head標籤內;
咱們先來看看我項目的結構以下:

所以你須要根據package.json來初始化本項目的依賴模塊,執行命令:npm install;html

其中less/main.less 文件以下代碼:java

@base:red;
body{
    margin:10px;
    background-color:@base;
}

如今我想經過html-webpack-plugin插件動態生成 html頁面及引入index.js 和 生成 index.js文件;node

webpack.config.js代碼配置以下:webpack

var path = require('path');
var HtmlwebpackPlugin = require('html-webpack-plugin');
//定義了一些文件夾的路徑
var ROOT_PATH = path.resolve(__dirname);
var SRC_PATH = path.resolve(ROOT_PATH, 'src');
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');

module.exports = {
  entry: SRC_PATH + "/js/index.js",
  output: {
    filename: "build.js",
    path: BUILD_PATH
  },
  module: {
    loaders: [
      {test: /\.less$/,loader: "style!css!less"}
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  plugins: [
    new HtmlwebpackPlugin({
      title: 'Hello World app',
      filename: 'index.html',
      inject: true,
      hash: true
    })
  ]
};

在項目的根目錄運行webpack,便可動態生成html文件和js文件,打開生成後的index.html便可看到css生效了,且css被動態內鏈到head標籤內了。es6

上面是使用webpack打包;如今咱們再來看看使用第二種方案來打包~web

使用gulp來進行打包正則表達式

咱們知道使用gulp來打包的話,那麼咱們須要在根目錄下須要新建 Gulpfile.js;同時須要安裝依賴包gulp和gulp-webpack,執行命令:npm install gulp gulp-webpack --save-devchrome

所以咱們這邊Gulpfile.js的源碼以下:

var gulp = require('gulp');
var webpack = require("gulp-webpack");
var webpackConfig = require("./webpack.config.js");
gulp.task('webpack', function () {
    var myConfig = Object.create(webpackConfig);
    return gulp
        .src('./js/index.js')
        .pipe(webpack(myConfig))
        .pipe(gulp.dest('./build'));
});
// 註冊缺省任務
gulp.task('default', ['webpack']);

而後修改一下webpack.config.js代碼,只須要將output中push屏蔽掉,以下所示:

output: {
    filename: "build.js"
   // path: BUILD_PATH
},

便可,而後再在命令行中輸入gulp便可生成build/build.js和index.html了,以下所示:

less-loader項目源碼地址http://download.csdn.net/detail/wdlhao/9613213
3、理解babel-loader加載器的使用
babel-loader加載器能將ES6的代碼轉換成ES5代碼,這使咱們如今可使用ES6了。
咱們先來看看我項目的結構以下:

首先安裝babel-loader。執行命令:npm install babel-loader –save-dev
固然你也須要根據package.json來初始化本項目的其餘依賴模塊,執行命令:npm install;
如上安裝完後,咱們在根目錄node_modules會生成文件,以下所示:
src/js/a.js,徹底是遵守es6的語法,代碼以下:
//es6的語法
let LOADER = true; 
//module.exports = LOADER;

class Project {
  constructor(name) {
    this.name = name;
  }
  start() {
    return "Project " + this.name + " starting";
  }
}
var project = new Project("Journal");
let projectName = project.start(); // "Project Journal starting"
module.exports = "安裝es6語法輸出:"+LOADER+","+projectName;

src/js/index.js,執行入口,用於輸出es6代碼結果,代碼以下:

var aMoudle = require('./a');
console.log(aMoudle);

如今咱們能夠在webpack.config.js裏面moudle.loaders配置加載器了,代碼以下:

var path = require('path');
var HtmlwebpackPlugin = require('html-webpack-plugin');
//定義了一些文件夾的路徑
var ROOT_PATH = path.resolve(__dirname);
var SRC_PATH = path.resolve(ROOT_PATH, 'src');
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');
module.exports = {
  entry: SRC_PATH + "/js/index.js",
  output: {
    filename: "build.js",
    path: BUILD_PATH
  },
  module: {
    loaders: [
      {test: /\.js$/, loader: 'babel'}
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  plugins: [
    new HtmlwebpackPlugin({
      title: 'Hello babel-loader',
      filename: 'index.html',
      inject: true,
      hash: true
    })
  ]
};

最後生成的build/index.html代碼以下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello babel-loader</title>
  </head>
  <body>
  <script type="text/javascript" src="build.js?906bc2a0e6ca45cdeddd"></script></body>
</html>

index.html在控制檯的打印效果爲:

說明用babel-loader加載器來執行es6代碼,執行成功。
babel-loader項目源碼地址: http://download.csdn.net/detail/wdlhao/9613208
4、webpack命令行常見使用的操做
 安裝  webpack 後,可使用  webpack 這個命令行工具。主要命令:  webpack <entry> <output> 。能夠切換到包含webpack.config.js的目錄運行命令:
  •     webpack: 啓動 執行一次開發時的編譯
  •     webpack  -w:若是你想當改變一個文件而讓webpack實時編譯
  •     webpack -p: 執行一次生成環境的編譯(壓縮)
  •      webpack  -d:對文件進行解壓縮,提供source map,方便調式代碼方便調試文件
  •     webpack --config customconfig.js:若是你想把默認的配置文件webpack.config.js改爲自定義文件
  •     webpack --watch :在開發時持續監控增量編譯(很快)
  •     webpack --display-error-details 顯示更多報錯信息
  •     webpack --display-chunks 展現編譯後的分塊
  •      webpack --colors 顯示靜態資源的顏色
  •     webpack --progress 顯示編譯進度
  •     webpack --display-reasons 顯示更多引用模塊緣由
  •     webpack --profile 輸出性能數據,能夠看到每一步的耗時 
  •     webpack --display-modules 默認狀況下node_modules下的模塊會被隱藏,加上這個參數能夠顯示這些被隱藏的模塊
  •     webpack --sort-chunks-by,--sort-assets-by,--sort-modules-by 將modules/chunks/assets進行列表排序
  •     webpack -help,查看webpack幫忙文檔
如今咱們以babel-loader項目爲例,展現webpack經常使用命令行的使用方法;

咱們下面來了解下 webpack -w,以下所示:

好比我在js文件裏面隨便增長一點代碼後,保存後,再刷新頁面便可能夠看到代碼生效了,無需從新運行webpack或者gulp,使用webpack -w 能夠實時打包。

 webpack -p 的含義是對進行打包後的文件進行壓縮代碼;好比我在以前使用chrome看打包後的代碼以下:

 

如上能夠看到,代碼是未壓縮的,可是當我在控制檯命令行中運行 webpack -p 命令後,以下所示:

 
咱們如今再到控制檯上看下代碼變成已經壓縮後的代碼了,以下所示:
webpack  -d 是提供未壓縮以前的源碼 方便代碼中的調式;以下所示:

當我運行如上所示後,咱們再來看看剛纔已經壓縮後的代碼變成什麼樣子呢?以下所示:

如上代碼能夠看到 咱們進行壓縮後的代碼,經過運行 webpack -d 命令後,便可還原未壓縮的代碼,這樣的話就能夠方便咱們線上調式代碼了。同時生成了一個map文件,bulid.js.map主要是方便調試。
webpack --watch :在開發時持續監控增量編譯(很快)與webpack -w效果同樣。如圖爲修改了代碼以後的表現:
webpack --display-chunks 展現編譯後的分塊
webpack --display-modules 顯示node_modules下的隱藏模塊
webpack -help,查看webpack幫忙文檔
 
5、用webpack內置組件UglifyJsPlugin來壓縮js和css
webpack已經內嵌了uglifyJS來完成對JS與CSS的壓縮混淆,無需引用額外的插件。
壓縮代碼以下:
new webpack.optimize.UglifyJsPlugin({    //壓縮代碼
   compress: {
       warnings: false
   },
   except: ['$super', '$', 'exports', 'require']    //排除關鍵字
})

這裏須要注意的是壓縮的時候須要排除一些關鍵字,不能混淆,好比$或者require,若是混淆的話就會影響到代碼的正常運行。
webpack.config.js代碼改成以下:

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

module.exports = {
  entry: {
    'index':'./src/index.js'
  },
  output: {
    path: path.resolve(__dirname, "./build"),
    filename: "[name].js"
  },
  module: {
    loaders: [
        {test: /.css$/, loader: 'style!css'}
    ]
  },
   //添加咱們的插件 會自動生成一個html文件
  plugins: [
    new HtmlwebpackPlugin({
      title: 'inner plugin:UglifyJsPlugin',
      filename: 'index.html',
      inject: true,
      hash: true,
      minify:{ //壓縮HTML文件
        removeComments:true,    //移除HTML中的註釋
        collapseWhitespace:true    //刪除空白符與換行符
      }
    }),
    new webpack.optimize.UglifyJsPlugin({    //壓縮代碼
       compress: {
           warnings: false
       },
       except: ['$super', '$', 'exports', 'require']    //排除關鍵字
    })
  ]
}
View Code
繼續運行下webpack能夠看到js已經被壓縮了;注意:可是貌似對es6的語法不能壓縮~
根據內置組件webpack進行代碼混淆,主要是針對生成後的js代碼,如index.js,代碼以下:

 

根據外部組件html-webpack-plugin中minify進行代碼壓縮,主要是針對index.html,用於清除裏面的註釋、空白符與換行符等。結果以下:

壓縮js和css項目的源碼地址http://download.csdn.net/detail/wdlhao/9613216

6、html-webpack-plugin(生成自定義html頁面)
這個插件用來簡化建立服務於 webpack bundle 的 HTML 文件,尤爲是對於在文件名中包含了 hash 值,而這個值在每次編譯的時候都發生變化的狀況。你既可讓這個插件來幫助你自動生成 HTML 文件,也可使用 lodash 模板加載生成的 bundles,或者本身加載這些 bundles。自動生成知足要求的html文件。
使用 npm 安裝這個插件:npm install html-webpack-plugin --save-dev
首先來看看項目的目錄結構以下:
運行命令 npm install 把依賴包加載出來;
接着在 webpack.config.js配置以下:
var path = require('path');
var HtmlwebpackPlugin = require('html-webpack-plugin');
//定義了一些文件夾的路徑
var ROOT_PATH = path.resolve(__dirname);
var SRC_PATH = path.resolve(ROOT_PATH, 'src');
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');

module.exports = {
  entry: SRC_PATH + "/js/index.js",
  output: {
    path: BUILD_PATH,
    filename: 'index.js'//輸出的文件名 合併之後的js會命名爲index.js
  },
  //添加咱們的插件 會按要求自動生成一個html文件
  module: {
    loaders: [
        {test: /.less$/, loader: "style!css!less"}
    ]
  },
  plugins: [
    new HtmlwebpackPlugin({
      title: 'Hello World app'//生成新的html頁面的title;
    })
  ]
};
在項目中的根目錄下 運行 webpack 就能生成build文件夾了,裏面會自動生成 兩個文件 index.html和index.js文件;
index.html代碼以下:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World app</title>
  </head>
  <body>
  <script type="text/javascript" src="index.js"></script></body>
</html>

標題title就是咱們配置上的;且合併了依賴的js文件;咱們能夠直接在本地訪問index.html 能夠看到能打印出依賴的文件js代碼了;能夠看到能夠解決依賴的問題;

html-webpack-plugin 還支持以下配置:

  • title: 用於生成的HTML文件的標題。
  • filename: 用於生成的HTML文件的名稱,默認是index.html。你能夠在這裏指定子目錄。
  • template: 模板文件路徑,支持加載器,好比 html!./index.html
  • inject: true | 'head' | 'body' | false ,注入全部的資源到特定的 template 或者 templateContent 中,若是設置爲 true 或者 body,全部的 javascript 資源將被放置到 body 元素的底部,'head' 將放置到 head 元素中。
  • favicon: 添加特定的 favicon 路徑到輸出的 HTML 文件中。
  • minify:{ //壓縮HTML文件 
      removeComments:true, //移除HTML中的註釋 
      collapseWhitespace:true //刪除空白符與換行符
    }
  • hash: true | false, 若是爲 true, 將添加一個惟一的 webpack 編譯 hash 到全部包含的腳本和 CSS 文件,對於解除 cache 頗有用。
  • cache: true | false,若是爲 true, 這是默認值,僅僅在文件修改以後纔會發佈文件。
  • showErrors: true | false, 若是爲 true, 這是默認值,錯誤信息會寫入到 HTML 頁面中
  • chunks: 容許只添加某些塊 (好比,僅僅 unit test 塊)
  • chunksSortMode: 容許控制塊在添加到頁面以前的排序方式,支持的值:'none' | 'default' | {function}-default:'auto'
  • excludeChunks: 容許跳過某些塊,(好比,跳過單元測試的塊)
下面的示例演示瞭如何使用這些配置:
filename:重命名輸出文件及設置;inject:設置輸出文件位置;hash:決定是否生成hash值;favicon;favicon路徑
webpack.config.js代碼以下:
 plugins: [
    new HtmlwebpackPlugin({
      favicon:'./src/img/favicon.ico',  //favicon路徑
      title: 'Hello World app',//生成新的html頁面的title;
      filename: 'home/home.html',
      inject: true,
      hash: true
    })
  ]

而後再在命令行中繼續運行webpack命令,能夠看到在build下會生成2個目錄, 第一個是home/home.html; 第二個是 index.js
再來看下home.html代碼以下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World app</title>
  <link rel="shortcut icon" href="favicon.ico"></head>
  <body>
  <script type="text/javascript" src="../index.js?f19ff1a103d13247bfb5"></script></body>
</html>

咱們發如今body裏面自動添加了外鏈的js文件而且該js文件帶有惟一的hash編碼,hash編碼能夠更好的實現js文件的緩存,加快渲染速度。

webpack-html-webpack-plugin(default)源碼地址爲http://download.csdn.net/detail/wdlhao/9613219

minify是用來壓縮和清潔html代碼

在webpack.config.js中添加,代碼以下:

plugins: [
    new HtmlwebpackPlugin({
      favicon:'./src/img/favicon.ico',  //favicon路徑
      title: 'Hello World app',//生成新的html頁面的title;
      filename: 'home/home.html',
      inject: true,
      hash: true,
      minify:{ //壓縮HTML文件
           removeComments:true,    //移除HTML中的註釋
           collapseWhitespace:true    //刪除空白符與換行符
      }
    })
  ]

 查看html生成後的文件能夠看到已經被壓縮了,形式上變成一行了。如圖:

webpack-html-webpack-plugin(minify)源碼地址爲http://download.csdn.net/detail/wdlhao/9613212

7、理解 extract-text-webpack-plugin(獨立打包樣式文件)

執行安裝命令: npm install extract-text-webpack-plugin 
而後再webpack.config.js 加入加載器配置項以下代碼:
var path = require('path');
var HtmlwebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
//定義了一些文件夾的路徑
var ROOT_PATH = path.resolve(__dirname);
var SRC_PATH = path.resolve(ROOT_PATH, 'src');
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');

module.exports = {
  entry: SRC_PATH + "/js/index.js",
  output: {
    filename: "build.js",
    path: BUILD_PATH
  },
  module: {
    loaders: [
      test:/\.less$/,
      loader: ExtractTextPlugin.extract(
            'css?sourceMap!' +
            'less?sourceMap'
      )
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  plugins: [
   // 內聯css提取到單獨的styles的css
    new ExtractTextPlugin("index.css"),
    new HtmlwebpackPlugin({
      title: 'Hello World app',
      filename: 'index.html',
      inject: true,
      hash: true
    })
  ]
};
在項目的根目錄運行 webpack 便可生效;會在build目錄下 生成 index.css文件,且在打包後的index.html會自動引入link標籤的css;
以下所示:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World app</title>
  <link href="index.css?3a51e24a9f1f95dd46e0" rel="stylesheet"></head>
  <body>
  <script type="text/javascript" src="build.js?3a51e24a9f1f95dd46e0"></script></body>
</html>
extract-text-webpack-plugin項目的源碼地址http://download.csdn.net/detail/wdlhao/9613209
8、webpack打包多個資源文件
咱們在開發頁面的時候,有時候須要有多個入口文件,作到文件是按需加載,這樣就可使用緩存提高性能;那麼咱們接下來須要如何配置呢?如今咱們繼續作demo,如今好比我如今的項目文件結構以下:
咱們直接看 webpack.config.js配置代碼變成以下:
entry: {
    'index':SRC_PATH + "/js/index.js",
    'main':SRC_PATH + "/js/main.js"
  },
  output: {
    filename: "[name].bundle.js",
    path: BUILD_PATH
  },

從上面的配置代碼咱們能夠看到 entry如今變成了一個對象了,而對象名也就是key會做爲下面output的filename屬性的[name]。固然entry也能夠是一個數組。

所以咱們直接 webpack運行下便可 在build文件下 生成2個入口文件 如上面的截圖所示,如今咱們能夠根據不一樣的頁面 引入不一樣的入口文件,實現按需加載文件。

webpack打包多個資源文件源碼地址以下http://download.csdn.net/detail/wdlhao/9613221

9、webpack對圖片的打包

我如今的項目文件結構以下:

 

圖片是 url-loader來加載的,咱們既能夠在css文件裏url的屬性;

首先先安裝 url-loader插件: npm install --save-dev url-loader

首先在src/js/index.js文件裏面加入以下代碼:

require('../less/main.less');

首先在src/less/main.less文件裏面加入以下代碼:

@color: red;
body {
    background:@color;
    background:url('../images/1.png') no-repeat;
}
src/images/1.png,本身添加的圖片;build文件夾是執行webpack以後的生成的內容;
webpack.config.js全部代碼以下:
var path = require('path');
var HtmlwebpackPlugin = require('html-webpack-plugin');
var webpack = require("webpack");
//定義了一些文件夾的路徑
var ROOT_PATH = path.resolve(__dirname);
var SRC_PATH = path.resolve(ROOT_PATH, 'src');
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');

module.exports = {
  entry: {
     "index": SRC_PATH + "/js/index.js"
  },
  output: {
    filename: "[name].js",
    path: BUILD_PATH
  },
  module: {
    loaders: [
      //.css 文件使用 style-loader 和 css-loader 來處理
      {
        test: /\.less$/,
        loader:'style!css!less?sourceMap'
      },
      {
        test: /\.js$/, 
        loader: 'babel'
      },
      {
        test: /.(png|jpg)$/, 
        loader: 'url?limit=8192&name=images/[hash:8].[name].[ext]'//這種寫法主要是用來設置圖片的存放路徑及圖片的生成名字如,build/images/43243234234.1.png
      }
      }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  plugins: [
    new HtmlwebpackPlugin({
        title: 'Hello World app',
        filename: 'index.html',
        inject: true,
        hash: true
    })
  ]
};
View Code

執行webpack後,在瀏覽器中查看顯示效果,如圖所示:

至此運用url-loader實現圖片打包,而且可以在css中正確運用打包後的圖片。

webpack對圖片的打包的源碼地址爲:http://download.csdn.net/detail/wdlhao/9613223
相關文章
相關標籤/搜索