30分鐘手把手教你學webpack實戰

30分鐘手把手教你學webpack實戰css

閱讀目錄html

什麼是webpack? 他有什麼優勢?前端

    首先對於不少剛接觸webpack人來講,確定會問webpack是什麼?它有什麼優勢?咱們爲何要使用它?帶着這些問題,咱們來總結下以下:node

    Webpack是前端一個工具,可讓各個模塊進行加載,預處理,再進行打包,它能有Grunt或Gulp全部基本功能。優勢以下:react

  1. 支持commonJS和AMD模塊。
  2. 支持不少模塊加載器的調用,可使模塊加載器靈活定製,好比babel-loader加載器,該加載器能使咱們使用ES6的語法來編寫代碼。
  3. 能夠經過配置打包成多個文件,有效的利用瀏覽器的緩存功能提高性能。
  4. 使用模塊加載器,能夠支持sass,less等處理器進行打包且支持靜態資源樣式及圖片進行打包。
  5. 更多等等。。。帶着這些問題咱們慢慢來學習webpack。

二:如何安裝和配置webpack

首先個人項目目錄結構是:文件名叫webpack,裏面只有一個main.html,代碼以下:git

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="src/react.min.js"></script>
 </head>
 <body>
    <div id="content"></div>
    <script src="build/build.js"></script>
 </body>
</html>

還有一個文件夾src,該文件夾存放了二個js文件;react.min.js源文件和main.js文件,main.js源碼以下:es6

/* 內容區模塊代碼 */
var ContentMode = React.createClass({
        render: function(){
            return (
                <div className="ContentMode">
                    <div class="contents">{this.props.contents}</div>
                    {this.props.children}
                </div>
            )
        }
});
/* 頁面div封裝 上面三個模塊 */
var Page = React.createClass({
    render: function(){
        return (
            <div className="homepage">
                <ContentMode  contents ="longen">this is one comment</ContentMode >
                <ContentMode  contents ="longen2">this is two comment</ContentMode >
            </div>
            )
        }
});
/* 初始化到content容器內 */
React.render(
       React.createElement(Page,null),document.getElementById("content")
);

該代碼是React.js代碼,是react.js入門學習一中的代碼複製過來的 爲了演示;github

安裝步驟以下:web

  1. 生成package.json文件;

首先咱們須要在根目錄下生成package.json文件,須要進入項目文件內根目錄下執行以下命令:npm init

如上經過一問一答的方式後會在根目錄下生成package.json文件,以下所示:

2 . 經過全局安裝webpack

執行命令以下:npm install -g webpack 以下所示:

在c盤下會生成node_modules文件夾中會包含webpack,此時此刻咱們可使用webpack命令了;

3. 配置webpack

每一個目錄下都必須有一個webpack.config.js,它的做用就比如Gulpfile.js、或者 Gruntfile.js,就是一個項目配置,告訴webpack須要作什麼。

以下是個人webpack.config.js代碼以下:

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "build/build.js"
  },
  module: {
    loaders: [
       //.css 文件使用 style-loader 和 css-loader 來處理
      { test: /\.css$/, loader: "style!css" },
      //.js 文件使用 jsx-loader 來編譯處理
      { test: /\.js$/,    loader: "jsx-loader" }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  plugins: []
};

entry 是頁面中的入口文件,好比我這邊的入口文件時main.js

output: 是指頁面經過webpack打包後生成的目標文件放在什麼地方去,我這邊是在根目錄下生成build文件夾,該文件夾內有一個build.js文件;

resolve: 定義瞭解析模塊路徑時的配置,經常使用的就是extensions; 能夠用來指定模塊的後綴,這樣在引入模塊時就不須要寫後綴,會自動補全。

plugins: 定義了須要使用的插件,好比commonsPlugin在打包多個入口文件時會提取公用的部分,生成common.js;

module.loaders:是文件的加載器,好比咱們以前react須要在頁面中引入jsx的js源碼到頁面上來,而後使用該語法,可是經過webpack打包後就不須要再引入JSXTransformer.js;看到上面的加載器;好比jsx-loader加載器就是表明JSXTransformer.js的,還有style-loader和css-loader加載器;所以在使用以前咱們須要經過命令把它引入到項目上來;所以須要以下命令生成下;

jsx-loader加載器 npm install jsx-loader --save-dev 以下:

Style-loader加載器 npm install style-loader --save-dev 以下:

css-loader 加載器 npm install css-loader --save-dev 以下:

局部安裝webpack 執行命令:npm install webpack --save-dev

咱們這邊乾脆把gulp的全局安裝和在項目中局部安裝也安裝下,稍後有用~

Gulp全局安裝 npm install -g gulp 以下:

在項目文件內,gulp局部安裝 使用命令 npm install gulp --save-dev 以下所示:

所以在咱們文件夾node_modules下生成文件以下:

如今咱們來執行命令 webpack; 以下所示:

 便可在根目錄下生成一個build文件夾中build.js 以下所示:

咱們還可使用以下命令:webpack --display-error-details 命令執行,這樣的話方便出錯的時候能夠查看更詳盡的信息;好比以下:

如今咱們再來刷新下頁面;看到以下:

能夠看到頁面渲染出來了,咱們接着來看看頁面中的請求:

能夠看到只有一個文件react.min.js的源文件和build.js 咱們剛剛生成的build.js文件了,所以咱們經過webpack進行打包後,咱們如今就再也不須要和之前同樣引入JSXTransformer.js了。咱們還能夠看看build.js內生成了那些js,這裏就不貼代碼了,本身能夠看看了~

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

使用gulp來進行打包

咱們知道使用gulp來打包的話,那麼咱們須要在根目錄下須要新建 Gulpfile.js;

所以咱們這邊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('./src/main.js')
        .pipe(webpack(myConfig))
        .pipe(gulp.dest('./build'));
});

// 註冊缺省任務
gulp.task('default', ['webpack']);

而後webpack.config.js代碼變爲以下:

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "build.js"
  },
  module: {
    loaders: [
       //.css 文件使用 style-loader 和 css-loader 來處理
      { test: /\.css$/, loader: "style!css" },
      //.js 文件使用 jsx-loader 來編譯處理
      { test: /\.js$/,    loader: "jsx-loader" }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  plugins: []
};

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

Github上的代碼以下: https://github.com/tugenhua0707/webpack/  本身能夠把壓縮包下載下來運行下便可。

三:理解webpack加載器

    Webpack提供了一套加載器,好比css-loader,less-loader,style-loader,url-loader等,用於將不一樣的文件加載到js文件中,好比url-loader用於在js中加載png/jpg格式的圖片文件,css/style loader用於加載css文件,less-loader加載器是將less編譯成css文件;

配置加載器

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "build.js",
    path: __dirname + '/assets/',
    publicPath: "/assets/"
  },
  module: {
    loaders: [
      {test: /.css$/, loader: 'style!css'},
      {test: /.(png|jpg)$/, loader: 'url-loader?limit=8192'}
    ]
  }
  resolve: {
extensions: ['', '.js', '.jsx'],
//模塊別名定義,方便後續直接引用別名,無須多寫長長的地址
alias: {
    a : 'js/assets/a.js',  // 後面直接引用 require(「a」)便可引用到模塊
    b : 'js/assets/b.js',
    c : 'js/assets/c.js'
}
  },
  plugins: [commonsPlugin, new ExtractTextPlugin("[name].css")]
}

module.loader: 其中test是正則表達式,對符合的文件名使用相應的加載器. 

/.css$/會匹配 xx.css文件,可是並不適用於xx.sass或者xx.css.zip文件.

url-loader 它會將樣式中引用到的圖片轉爲模塊來處理; 配置信息的參數「?limit=8192」表示將全部小於8kb的圖片都轉爲base64形式。

entry 模塊的入口文件。依賴項數組中全部的文件會按順序打包,每一個文件進行依賴的遞歸查找,直到全部模塊都被打成包;

output:模塊的輸出文件,其中有以下參數:

filename: 打包後的文件名

path: 打包文件存放的絕對路徑。

publicPath: 網站運行時的訪問路徑。

relolve.extensions: 自動擴展文件的後綴名,好比咱們在require模塊的時候,能夠不用寫後綴名的。

relolve.alias: 模塊別名定義,方便後續直接引用別名,無須多寫長長的地址

plugins 是插件項;

四:理解less-loader加載器的使用

    咱們先來理解下less-loader加載器,其餘的sass-loader也是一個意思,這邊不會對全部的預處理的css作講解,less-loader加載器是把css代碼轉化到style標籤內,動態插入到head標籤內;咱們先來看看我項目的結構以下:

咱們如今css文件下有一個main.less 代碼以下:

@base: #f938ab;
html,body {
  background:@base;
}

Src文件下有一個main.js文件 此js文件時入口文件;裏面的代碼以下:

// css

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

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

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "build.js",
    path: __dirname
  },
  module: {
    loaders: [
      //.css 文件使用 style-loader 和 css-loader 來處理
      {
        test: /\.less$/,
        loader: "style!css!less"
      }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  plugins: []
};

Gulpfile.js代碼以下(注意:這邊既能夠須要此文件使用gulp進行運行打包,也能夠不須要此文件,直接使用webpack進行打包;二種方式任選其一)。

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('./src/main.js')
        .pipe(webpack(myConfig))
        .pipe(gulp.dest('./build'));
});

// 註冊缺省任務
gulp.task('default', ['webpack']);

所以咱們須要安裝 style-loader css-loader 和 less-loader 以下所示:

 安裝完成後,咱們查看咱們的項目的根目錄node_modules下多了以下幾個文件:

如上配置後,咱們進入項目後 運行下 gulp或者 webpack命令既可,在build文件夾內會生成build.js,此JS是動態生成style標籤並解釋正常的css插入到文檔head標籤內;咱們能夠運行下頁面,查看代碼看下以下:

所以咱們能夠看到頁面生效了;爲了更好的demo測試,我把代碼放到以下github上,本身能夠下載下來運行下既可: https://github.com/tugenhua0707/webpack-less-loader

五:理解babel-loader加載器的含義

babel-loader加載器能將ES6的代碼轉換成ES5代碼,這使咱們如今可使用ES6了;咱們在使用以前,咱們須要安裝babel-loader

執行命令:npm install babel-loader –save-dev 以下所示:

如上安裝完後,咱們在根目錄node_modules會生成文件,以下所示:

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

{test: /\.js$/, loader: 'babel', exclude: '/node_modules/'} 

所以webpack.config.js代碼變成以下:

// 使用webpack打包
module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "build.js",
    path: __dirname
  },
  module: {
    loaders: [
      {test: /\.js$/, loader: 'babel', exclude: '/node_modules/'}
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  plugins: []
};

下面咱們再來看看我項目中的目錄結構以下:

咱們在看看src源文件有下面幾個文件

React.min.js是react源碼,這個很少說,bind.js的ES6的代碼以下:

// es6的語法 let LOADER = true; module.exports = LOADER;

main.js 是頁面的入口文件;代碼以下:

let loader = require('./bind');
console.log(loader);

let是ES6的語法 至關於js中的var定義變量的含義; 接着打印下bind模塊中 打印爲true;

最後執行gulp以下:

在控制檯中打印true;我把源碼放在github上,有須要的同窗能夠本身下載下來運行下便可;以下github(我2年沒有使用github,如今從新使用,爲了更好的演示demo問題); https://github.com/tugenhua0707/webpack-babel-loader

六:瞭解下webpack的幾個命令

  1. webpack         // 最基本的啓動webpack的方法
  2. webpack -w      // 提供watch方法;實時進行打包更新
  3. webpack -p      // 對打包後的文件進行壓縮
  4. webpack -d      // 提供source map,方便調式代碼

咱們下面來了解下 webpack -w

以下所示:

好比我在js文件裏面隨便增長一點代碼後,保存後,再刷新頁面便可能夠看到代碼生效了,無需從新運行webpack或者gulp,使用webpack -w 能夠實時打包。 webpack -p 的含義是對進行打包後的文件進行壓縮代碼;好比我在以前使用chrome看打包後的代碼以下:

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

咱們如今再到控制檯上看下代碼變成已經壓縮後的代碼了,以下所示:

webpack  -d 是提供未壓縮以前的源碼 方便代碼中的調式;以下所示:

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

如上代碼能夠看到 咱們進行壓縮後的代碼,經過運行 webpack -d 命令後,便可還原未壓縮的代碼,這樣的話就能夠方便咱們線上調式代碼了。

咱們再來看看目錄下 會生成map文件,以下所示:

七:webpack對多個模塊依賴進行打包

   經過一剛開始咱們瞭解到 webpack支持commonJS和AMD兩種模塊機制進行打包,所以咱們如今來針對代碼中使用commonJS和AMD機制進行作一個demo;

Src源文件增長module1.js module2.js module3.js 代碼分別以下:

module1.js 代碼:
// module1.js
require(["./module3"], function(){
    console.log("Hello Webpack!");
});

Module2.js代碼以下:
// module2.js,使用的是CommonJs機制導出包
module.exports = function(a, b){
    return a + b;
}

Module3.js代碼使用AMD機制

// module3.js,使用AMD模塊機制
define(['./module2.js'], function(sum){
    return console.log("1 + 2 = " + sum(1, 2));
});
 // 入口文件 main.js 代碼以下:
 require("./module1");

咱們能夠運行下 webpack後 在根目錄下生成以下文件:

其中1.build文件夾是commonJS生成的 裏面是commonJS的代碼;咱們再查看頁面的代碼以下能夠看到:

 

咱們繼續查看控制檯輸出以下:

爲止咱們能夠看到webpack打包能夠支持commonJS模塊和AMD模塊。

具體的代碼 能夠查看個人github上的源碼:

https://github.com/tugenhua0707/webpack-multi-module-depend 

八:如何獨立打包成樣式文件

    有時候咱們不想把樣式打在腳本中,而是想獨立css出來,而後在頁面上外鏈css,這時候咱們須要 extract-text-webpack-plugin 來幫忙:咱們首先須要安裝 extract-text-webpack-plugin:以下: npm install extract-text-webpack-plugin –save-dev 以下所示:

而後在目錄下會生成以下:

如今咱們須要看看webpack.config.js 配置變成以下:

var ExtractTextPlugin = require("extract-text-webpack-plugin");
// 使用webpack打包
module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "build.js"
  },
  module: {
    loaders: [
      //.css 文件使用 style-loader 和 css-loader 來處理
      {
        test: /\.less$/,
        loader: ExtractTextPlugin.extract(
            'css?sourceMap!' +
            'less?sourceMap'
        )
      }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  // 內聯css提取到單獨的styles的css
  plugins: [new ExtractTextPlugin('styles.css')]
};

配置完成後 咱們gulp運行下便可,在build文件夾內會生成2個文件,一個是build.js 處理模塊的文件 另外一個就是咱們的styles.css了;咱們查看下以下所示:

接着在html文件這樣引入便可:

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="src/react.min.js"></script>
  <link rel="stylesheet" href="build/styles.css"/>
 </head>
 <body>
    <div id="content"></div>
    
 </body>
</html>

在頁面上運行如下;便可看到效果:咱們能夠看下請求數:

具體的代碼demo能夠看個人github 以下:

https://github.com/tugenhua0707/extract-text-webpack-plugin 

注意:node_modules模塊沒有上傳上去,git上傳不上去,總是提示Filename too long的錯誤,因此就沒有上傳,須要本身在本地安裝以下模塊:

九:如何打包成多個資源文件

    咱們在開發頁面的時候,有時候須要有多個入口文件,作到文件是按需加載,這樣就可使用緩存提高性能;那麼咱們接下來須要如何配置呢?如今咱們繼續作demo,如今好比我如今的項目文件結構以下:

咱們直接看 webpack.config.js配置代碼變成以下:

module.exports = {
  entry: {
     "main": "./src/main.js",
     "index": "./src/index.js"
  },
  output: {
    filename: "[name].bundle.js"
  }
};

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

所以咱們直接 gulp運行下便可 在build文件下 生成2個入口文件 如上面的截圖所示:github源碼地址以下:

https://github.com/tugenhua0707/webpack-many-page 

如今咱們能夠根據不一樣的頁面 引入不一樣的入口文件,實現按需加載文件。

十:關於對圖片的打包

咱們知道圖片是使用url-loader來加載的,咱們既能夠在css文件裏url的屬性;以下:

#content{
    width:170px;
    height:60px;
    background:url('../images/1.jpg') no-repeat;
}

咱們還能夠直接對元素的src屬性進行require賦值。以下代碼:

var img = document.createElement("img"); 
img.src = require("../image/1.jpg"); 
document.body.appendChild(img);

我這邊直接來說第一種在css文件裏的url屬性進行打包;

首先來看看我項目的目錄結構以下:

Css文件 main.css代碼以下:

#content{
    width:170px;
    height:60px;
    background:url('../images/1.jpg') no-repeat;
}

JS文件main.js代碼以下:

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

Webpack.config.js配置文件代碼以下:

// 使用webpack打包
module.exports = {
  
  entry: {
     "main": "./src/main.js"
  },
  output: {
    path: './build/',
    filename: "build.js"
  },
  module: {
    loaders: [
      {test: /.css$/, loader: 'style!css'},
      {test: /.(png|jpg)$/, loader: 'url?limit=8192'}
    ]
  }
};

直接運行webpack 能夠生成build目錄,build目錄下會生成2個文件 一個是圖片打包後,另一個是build.js。接着咱們再在頁面運行下頁面,發現有一個問題,以下:

頁面調用圖片的url是根目錄下的,不是我打包後的 build文件夾下,因此會致使圖片路徑找不到的問題;所以這邊有一點點沒有完成的任務,但願有興趣的童靴能夠幫助完成~ 不過圖片確實是已經打包好了,爲了方便,咱們仍是提供github源碼吧!以下所示:

https://github.com/tugenhua0707/webpack-url-loader 

十一:React開發神器:react-hot-loader

 待續..... 因爲篇幅有限~~  這個留給下篇文章講解。

相關文章
相關標籤/搜索