【原】webpack學習筆記


    之前在react的項目中有用過webpack,不過沒有認真的去研究,這段時間又重新好好的學習一下webpack,發覺 webpack是一個很強大的東西。而且很好用,方便,接下來主要是做一下學習的筆記

這次我還是在react中來使用它。我的react界面是單頁面的應用

    首先你的項目的根目錄下要有一個package.json文件,來進行安裝一下相應的依賴

package.json如下

"devDependencies": {
    "css-loader": "^0.23.1",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.8.5",
    "html-loader": "^0.4.3",
    "html-webpack-plugin": "^2.9.0",
    "jquery": "^1.12.0",
    "less": "^2.6.0",
    "less-loader": "^2.2.2",
    "style-loader": "^0.13.0",
    "url-loader": "^0.5.7",
    "webpack": "^1.12.13",
    "webpack-dev-server": "^1.14.1",
    "react-router":"^1.0.0",
     "react": "^0.14.0",
     "react-dom": "^0.14.0",
}

  

 

然后npm install就行依賴文件的安裝

 

大概的目錄結構是這樣子

  +router               #路由存放界面
      +IndexComponent #組件
        -index.js
      -otherComponent #組件
        -other.js
    +css                 #css存放目錄
    -index.css
    -other.css
    +images              #圖片資源
    +dist               #webpack編譯打包輸出目錄,無需建立目錄可由webpack根據配置自動生成
        -css                
        -js
    +app.js              #路由的入口文件
   +index.html
    + node_modules       #所使用的nodejs模塊
    package.json         #項目配置
    webpack.config.js    #webpack配置

  

  

index.html 內容如下:

這里我們還是需要手動引入的。  可以看到,我們只是引用了打包后的css和js,這個后面有說。先引入進去先

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
<title>webpack學習</title>
  <link rel="stylesheet" type="text/css" href="dist/css/app.css"> 
</head>
<body">
  <div" id="index"></div>
     <script src="dist/js/vendor.bundle.js"></script>
  <script src="dist/js/app.bundle.js"></script>
</body>
</html>

 

在react中,我們引入css是直接在js中引入的,比如我們的 index.js,當然,你也可以直接在html引入一個總的css

 import React from 'react';
//引入css
 require("../css/index.css");

const Index= React.createClass({

  render(){

    return (
         <div> hello world</div>    
      )
   }
});

export default Index;

  

other.js:

 import React from 'react';
//引入css
 require("../css/other.css");

const Other= React.createClass({

  render(){

    return (
         <div>this  is other component</div>    
      )
   }
});

export default Other;

  

app.js    路由的入口文件。

其實內容隨便寫都行,因為主要是用來演示一下webpack的打包而已,並不是演示react-router

app.js

import { render } from 'react-dom'
import { Router, Route, IndexRoute, Link, IndexLink } from 'react-router'

import Index from '../router/IndexComponent/index.js'
import Other from '../router/OtherComponent/other.js'

render((
  <Router>
    <Route path="/" component={Index}>
      <IndexRoute component={Index} />
      <Route path="other" component={Other} />
    </Route>
  </Router>
), document.getElementById('index'))

 

webpack  配置及項目打包編譯

這里是關鍵,在根目錄下我們新建一個webpack.config.js,我們將進行一些配置,來完成我們的需求。剛開始可能不好理解,沒關系測試多幾次,你就會發覺它的神奇之處。

var path = require('path');
var webpack = require('webpack');
/*
extract-text-webpack-plugin插件,
將你的樣式提取到單獨的css文件里,如果沒有它的話,webpack會將css打包到js當中
 */
var ExtractTextPlugin = require('extract-text-webpack-plugin');
/*
html-webpack-plugin插件,webpack中生成HTML的插件,
可以將打包好的文件動態加載到html中
 */
var HtmlWebpackPlugin = require('html-webpack-plugin');
 
module.exports = {
    entry: { //配置入口文件,有幾個寫幾個。我這里有兩個文件。一個是所有我需要引入的文件,一個是我的入口文件,app.js
    //支持數組形式,將加載數組中的所有模塊,但以最后一個模塊作為輸出,比如下面數組里面的js,全部壓縮在了vendor這個文件這里
    vendor: ['react','react-dom','react-router'],
     app: [ './app.js'],
    },
    output: {
        path: path.join(__dirname, 'dist'),  //輸出目錄的配置,模板、樣式、腳本、圖片等資源的路徑配置都相對於它.名字可以隨便起
        // publicPath: '/dist/',               很多教程的publicPath是這個,你會發覺不能動態加載到html中,會報錯,實際上是下面的寫法才對
        publicPath: '../',                //模板、樣式、腳本、圖片等資源對應的server上的路徑
        filename: 'js/[name].bundle.js',       //每個頁面對應的主js的生成配置。比如我的app.js打包后就為  js/app.bundle.js
        chunkFilename: 'js/[id].bundle.js'   //dundle生成的配置
    },
    module: {
        loaders: [ //加載器,關於各個加載器的參數配置。
        {
        test: /\.js$/,
        loaders: ['react-hot', 'babel'],
        include: [path.join(__dirname, ''), path.join(__dirname, 'router')]  //我需要打包的js所在的目錄
        },
 
       {
                test: /\.css$/,
                //配置css的抽取器、加載器。'-loader'可以省去
                loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
            }, {
                test: /\.less$/,
                //配置less的抽取器、加載器。中間!有必要解釋一下,
                //根據從右到左的順序依次調用less、css加載器,前一個的輸出是后一個的輸入
                //你也可以開發自己的loader喲。有關loader的寫法可自行谷歌之。
                loader: ExtractTextPlugin.extract('css!less')
            }, {
                //html模板加載器,可以處理引用的靜態資源,默認配置參數attrs=img:src,處理圖片的src引用的資源
                //比如你配置,attrs=img:src img:data-src就可以一並處理data-src引用的資源了,就像下面這樣
                test: /\.html$/,
                loader: "html?attrs=img:src img:data-src"
            }, {
                //文件加載器,處理文件靜態資源
                test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: 'file-loader?name=./fonts/[name].[ext]'
            }, {
                //圖片加載器,雷同file-loader,更適合圖片,可以將較小的圖片轉成base64,減少http請求
                //如下配置,將小於8192byte的圖片轉成base64碼
                // base的好處可以看看這篇文章
                // http://www.zhangxinxu.com/wordpress/2012/04/base64-url-image-%E5%9B%BE%E7%89%87-%E9%A1%B5%E9%9D%A2%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/
                test: /\.(png|jpg|gif)$/,
                loader: 'url-loader?limit=8192&name=./img/[hash].[ext]'
            }
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({ //加載jq
            $: 'jquery',
      _:'underscore' //加載underscore
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendors',   // 將公共模塊提取,生成名為`vendors`bundle
            chunks: ['vendor'], //提取哪些模塊共有的部分,名字為上面的vendor
            minChunks: Infinity // 提取至少*個模塊共有的部分
        }),
        new ExtractTextPlugin('css/[name].css'), //單獨使用link標簽加載css並設置路徑,相對於output配置中的 publickPath
            
        // 有幾個頁面就寫幾個
       new HtmlWebpackPlugin({                        //根據模板插入css/js等生成最終HTML
             favicon:'./images/favicon.ico', //favicon存放路徑
             filename:'/view/index.html',    //生成的html存放路徑,相對於 path
             template:'./index.html',    //html模板路徑
             inject:true,    //允許插件修改哪些內容,包括head與body
             hash:true,    //為靜態資源生成hash值
             chunks: ['vendor', 'app'], //需要引入的chunk,不配置就會引入所有頁面的資源.名字來源於你的入口文件
             minify:{    //壓縮HTML文件
                 removeComments:true,    //移除HTML中的注釋
                 collapseWhitespace:false    //刪除空白符與換行符
             }
         })
         
        new webpack.HotModuleReplacementPlugin() //熱加載
    ],
    //使用webpack-dev-server,提高開發效率
    devServer: {
        contentBase: './',
        host: 'localhost',
        port: 3200, //比如我是監聽3200端口
        inline: true, //可以監控js變化
        hot: true, //熱啟動
    }
};

 

 好了,此時你在cmd輸入 webpack  就會看到在dist那里會生成兩個目錄,js和css這兩個文件夾,js里面有vendor.bundle.js和app.bundle.js. css里面你會發覺只有一個app.css。

 

 

html-webpack-plugin 插件,動態為html加入js和css

  在前面的html中,我們是手動引入css和html的。但是webpack的這個插件可以動態將我們的js和css自動加載到html 上,也就是說。可以將

index.html改為

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
<title>webpack學習</title>
<!--  這里無需引入樣式 -->
</head>
<body">
  <div" id="index"></div>
    <!-- 也不在需要引入js -->
</body>
</html>

不過我覺得這個動態加載js和css的方法用不用都無所謂。

 

注意:

在網上的教程中,你會發覺有些動態加載js和css到html中會報錯。提示找不到那個路徑,這是為什么呢,因為是他們的 publicPath這里錯了。

 他們的是     publicPath: '/dist/',

 而實際上應該改為  publicPath: '../', 

 

解決打包后圖片出現的路徑問題:

問題:

  打包后,你有會發覺另一個問題,就是背景圖中,小一點的圖片會被轉為base64,可以正常演示,但是我本地的圖片,img的src中卻找不到路徑了。會報錯。這個問題比較詭異,我網速找了好多資料都沒找到怎么解決的。后來自己隨便亂搞,總結出來3個解決方法:

 

方法1、你在引入圖片的時候用這樣來引入,那么就不會報錯了

<img src={require("../images/cd_03.png")} />

不過我是用在react當中的,其他地方暫時沒試過。雖然我的方法可以本地圖片加載出來,不過始終覺得不是一個好方法

 

方法2:將webpack.config.js 配置中的

loader: 'url-loader?limit=8192&name=./img/[hash].[ext]'

 改為下面這樣:

loader: 'url-loader?limit=1&name=[path][name].[ext]'

這樣子修改之后,小於8k的圖片不會轉為base64,而且圖片的名字也不會變成hash值。這樣就可以找到路徑了。那么如果很多比較小的圖片怎么辦呢,那就只能做好雪碧圖了。

 

方法3 :

將你的圖片放到cnd上,引入圖片的之后直接引入你線上的鏈接,這樣的話圖片就不會被打包,從而避免了圖片的路徑問題。不過要手動改動挺大的

 

這里順便粘貼一下我的server.js.在根目錄下

server.js

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
process.env.NODE_ENV='production'
new WebpackDevServer(webpack(config), {
  publicPath: '/dist/',
  hot: true,
  historyApiFallback: true
}).listen(3200, 'localhost', function (err, result) {
  if (err) {
    console.log(err);
  }

  console.log('Listening at localhost:3200');
});

 

最后附上 webpack命令的幾種基本命令

webpack命令行的幾種基本命令(https://webpack.github.io/docs/cli.html)

$ webpack -h
$ webpack       //最基本的啟動webpack方法,執行一次編譯  for building once for development 
$ webpack -w 或  --watch //增量編譯,監聽變動並進行自動實時打包更新 for continuous incremental build in development (fast!)
$ webpack -p // 壓縮混淆腳本,對打包后的文件進行壓縮,for building once for production (minification)
$ webpack -d // 生成 SourceMaps映射文件,告知哪些模塊被最終打包到哪里,方便調試。 to include source maps
$ webpack --display-error-details 查看查找過程,方便出錯時能查閱更詳盡的信息
$ webpack --config XXX.js 使用另一份配置文件來打包
webpack --colors 輸出結果帶彩色,比如:會用紅色顯示耗時較長的步驟
webpack --profile 輸出性能數據,可以看到每一步的耗時
webpack --display-modules 默認情況下node_modules下的模塊會被隱藏,加上這個參數可以顯示這些被隱藏的模塊

  

這篇文章主要是記錄一下學習webpack的筆記,具體的大家還是需要實際操作一下。webpack真的是一個神奇的東西,不單單是用在react的打包當中,用在前端的任何框架下打包都是可以的。可以說是gulp的2.0版本。值得一玩

用在react當中打包壓縮的話,一個項目下來,所有的文件加起來也不過幾百k,對性能肯定是有好處的。

 有一篇很不錯的,關於webpack的文章,可以看看 https://llp0574.github.io/2016/11/29/getting-started-with-webpack2/


免責聲明!

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



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