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


您的閱讀目錄:
一、理解webpack加載器loader
1.1、什么是loader?
webpack的設計理念,所有資源都是“模塊”,webpack內部實現了一套資源加載機制。loaders 用於轉換應用程序的資源文件,他們是運行在nodejs下的函數 使用參數來獲取一個資源的來源並且返回一個新的來源(資源的位置),例如你可以使用loader加載器可以快速編譯預處理器(less,sass,coffeeScript)。
1.2、使用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。

// 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.

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

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

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

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

現在我想通過html-webpack-plugin插件動態生成 html頁面及引入index.js 和 生成 index.js文件;

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: {
    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標簽內了。

上面是使用webpack打包;現在我們再來看看使用第二種方案來打包~

使用gulp來進行打包

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

因此我們這邊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
三、理解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
四、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幫忙文檔
 
五、用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

六、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

七、理解 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
八、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

九、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
 
 
 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM