1. 程式人生 > >如何使用webpack打包前端項目

如何使用webpack打包前端項目

filename get put http 根目錄 file 命令 lan yarn

webpack概述

隨著前端體積越來越大,功能越來越豐富,這時候就需要將前端工程化,而
webpack就是用於將前端各種文件打包起來。
一個簡單的webpack應該包含以下幾個概念
· 入口起點
· 輸出
· 配置
· 組件
· 加載器
· 插件
· 模塊
· 模塊熱替換
下面我們一步步的搭建webpack,逐步講解上訴模塊

開發環境

推薦使用JetBrain的Webstorm,有強大的代碼提示,支持JSX和ES6語法;
我們將會使用npm來下載和構建依賴,現在網上也有很多人使用yarn來安裝,不過沒關系,兩者都是工具,npm已經夠用;
需要提前安裝node.js,下載地址https://nodejs.org/en/download/,我這裏下載的是node-v6.9.2-x64.msi,一路默認安裝即可;
安裝完成之後,打開CMD命令行,分別輸入node -v和npm -v,兩者都能看見版本號即表示安裝成功

項目結構

首先,webpack處理流程是entry=> rules(loaders)=> webpack=> output
entry是入口,rules或者loaders是加載器,webpack打包,output輸出
下面我們來一步步的執行上訴流程

使用Webstorm新建一個新項目,命名為demo1,
我們先手動建立輸出目錄文件夾build和並在build文件夾下建立輸出文件index.html(最終要呈現的頁面文件)
在index.html中添加代碼如下

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo1</title>
</head>
<body>
</body>
</html>

接下來我們將package.json和webpack安裝到我們新建的項目中去

創建package.json文件

package.json是一個標準的npm說明文件,裏面蘊含了豐富的信息,包括當前項目的依賴模塊,自定義的腳本任務等;
打開cmd命令行,使用cd命令切換到你創建demo1目錄下,然後輸入

npm init -yes

可以自動創建package.json文件
切換到項目文件夾即可看到package.json文件創建完成

安裝webpack

接下來我們需要在本項目中安裝webpack作為依賴包,寫入項目的package.json文件中

npm install --save-dev webpack

--save-dev是nodejs的一條命令,用於將npm安裝的webpack各種依賴信息(dev)保存到(save)到package.json中去
查看項目,出現node_modules文件夾即表示安裝成功

node_modules我們可以模糊理解為sdk中的庫文件,我們後續用的babel、browserify、require等在該文件夾中都能知道其定義,我們也可以自定義第三方包放在改目錄下供我們程序使用
安裝好package.json和webpack之後,我們開始搭建我們需要的工程

技術分享圖片

上述三個步驟後,我們應該出現上圖所示工程

創建webpack.config.js

下面,我們上述安裝的webpack和建立的demo1工程關聯起來
建立src,在其新建文件hello.js,並寫入代碼

module.exports = function() {
    var hello = document.createElement(‘div‘);
    hello.textContent = "Hi everybody!";
    return hello;
};

新建src/main.js,寫入代碼

var hello = require(‘./hello.js‘);
document.getElementById(‘content‘).appendChild(hello());

修改index.html代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo1</title>
</head>
<body>
<!--要插入React組件的位置-->
<div id="content"></div>
<!--引入bundle.js-->
<script src="bundle.js"></script>
</body>
</html>

在項目的根目錄下新建webpack.config.js文件,webpack.config.js是webpack的配置文件,與package.json不同是,它是給webpack用的
webpack.config.js代碼如下:

//__dirname是node.js中的一個全局變量,它指向當前執行腳本所在的目錄
module.exports = {//註意這裏是exports不是export
    entry: __dirname + "/src/main.js",//唯一入口文件
    output: {//輸出目錄
        path: __dirname + ‘/build‘,//打包後的js文件存放的地方
        filename: ‘bundle.js‘//打包後輸出的js的文件名
    },
};

bundle.js是src文件夾下的文件經webpack打包後最終生成的供瀏覽器解析的js文件,這個不需要手動進行配置,甚至你不需要新建它,由webpack自動生成,後續我們會講解它;

項目打包

這時候已經可以使用webpack進行打包了
在命令行下輸入webpack執行打包(這裏我們已經切換到項目目錄,故可以直接使用webpack)

webpack

看到以上提示說明打包成功了,可以看到build目錄下的自動生成了bundle.js,並且多了很多自動生成的代碼。
直接雙擊打開index.html,可以看到,我們在hello.js裏寫的代碼已經顯示到頁面上了
這裏,可以理解為index.html是一個頁面,main.js是一個裝載器,hello.js是一個組件,通過main將hello組件裝載到index頁面中

至此,一個最簡單的webpack工程已經打包好了,下面我們逐漸豐富webpack的配置

安裝並啟用webpack-dev-server
我們可以使用webpack-dev-server來搭建本地開發服務器,
文件修改能被監聽,並自動刷新瀏覽器,即模塊熱替換功能

現在我們需要啟動模塊熱替換,我們先安裝webpack-devserver

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

打開文件package.json,發現devDependencies依賴中多了webpack-dev-server配置,即表示安裝成功
使用webpack-dev-server後,我們在package.json的scripts中添加如下代碼

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

並且且在index.html裏加入:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ReactDemo1</title>
</head>
<body>
<!--要插入React組件的位置-->
<div id="content"></div>
<!--引入bundle.js-->
<script src="http://localhost:8080/webpack-dev-server.js"></script>
<script src="bundle.js"></script>
</body>
</html>
在webpack.config.js中配置webpack-dev-server,在這裏需要修改下entry的路徑,給它加一個webpack/hot/dev-server,這裏會用到Hot Module Replacement(熱替換)插件,所以需要增加這個前綴,後文會提到,代碼如下:
//__dirname是node.js中的一個全局變量,它指向當前執行腳本所在的目錄
module.exports = {//註意這裏是exports不是export
    entry: [‘webpack/hot/dev-server‘, __dirname, ‘./src/main.js‘],
    output: {//輸出目錄
        path: __dirname + "/build",//打包後的js文件存放的地方
        filename: "bundle.js"//打包後的js文件名
    },
   //webpack-dev-server配置
   devServer: {
        contentBase: ‘./build‘,//默認webpack-dev-server會為根文件夾提供本地服務器,如果想為另外一個目錄下的文件提供本地服務器,應該在這裏設置其所在目錄(本例設置到"build"目錄)
        historyApiFallback: true,//在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置為true,所有的跳轉將指向index.html
        port: 8080//設置默認監聽端口,如果省略,默認為"8080"
   }
};

最後執行

npm run dev

你只要在瀏覽器打開這個地址:
http://localhost:8080/
webpack-dev-server會為你準備好一切,你只要敲一敲鍵盤,save一下,所見即所得。

這裏dev的作用相當於tomacat,是一個基於node.js的小型的服務器,如果需要停止服務,在終端按ctrl+c,按提示輸入Y即可。

我們嘗試修改下hello.js裏的內容,發現並沒有變化,按F12查看控制臺,發現報以下的錯誤

這裏就需要引入一個HDR插件

Hot Module Replacement插件

Hot Module Replacement(HMR)是webpack裏很有用的一個插件,它允許你在修改組件代碼後,自動刷新實時預覽修改後的效果。
在webpack中實現HMR也很簡單,只需要在webpack.config.js中引入HMR插件,並在devServer中將inline設置為true,代碼如下:

var webpack = require(‘webpack‘);
//__dirname是node.js中的一個全局變量,它指向當前執行腳本所在的目錄
module.exports = {//註意這裏是exports不是export
    entry: [‘webpack/hot/dev-server‘, __dirname + ‘/src/main.js‘],
    output: {//輸出目錄
        path: __dirname + "/build",//打包後的js文件存放的地方
        filename: "bundle.js"//打包後的js文件名
    },
    //webpack-dev-server配置
    devServer: {
        contentBase: ‘./build‘,//默認webpack-dev-server會為根文件夾提供本地服務器,如果想為另外一個目錄下的文件提供本地服務器,應該在這裏設置其所在目錄(本例設置到"build"目錄)
        historyApiFallback: true,//在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置為true,所有的跳轉將指向index.html
        inline: true,//設置為true,當源文件改變時會自動刷新頁面
        port: 8080,//設置默認監聽端口,如果省略,默認為"8080"
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()//熱模塊替換插件
    ]
};

在webpack中,我們都是使用的plugins來引入插件的使用
執行
npm run dev
返回webstrom,我們去修改hello.js組件中的代碼,保存後發現,瀏覽器的值直接改變了,甚至都不需要我們去刷新頁面,相當的方便

擴展

安裝React

在加載器、插件、模塊中,我們需要使用react來配合使用,首先安裝react
這裏,我們同時安裝React和React-DOM

npm install --save-dev react react-dom

安裝配置Babel

它是一個JavaScript編譯器。使用它的目的有兩個:
· 讓代碼支持ES6語法
· 支持React的一些特性(如JSX語法)
標準的React組件後綴名為.jsx,而.jsx是默認不被瀏覽器所支持的;所以需要一個轉換器,將不被瀏覽器識別的.jsx文件轉換成瀏覽器能夠正常運行的文件,這個轉換器就是Babel。
Babel loader用於文件特定格式的轉換

// 安裝 babel-core 核心模塊 babel-loader ES6 和 React 支持
npm install babel-core babel-loader babel-preset-es2015 babel-preset-react --save-dev

查看package.json,會多出如下代碼,表示安裝成功
新建src/first.jsx文件,添加如下代碼,這裏要確保安裝了React和React-DOM

const React = require(‘react‘);
const ReactDOM = require(‘react-dom‘);
ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.querySelector(‘#content‘)
);

修改main.js的內容

// var hello = require(‘./hello.js‘);
// document.getElementById(‘content‘).appendChild(hello());
document.write(‘<h1>Hello World</h1>‘);
webpack.config.js中將first.jsx設置為我們的入口文件,並且添加module模塊和loader加載器,這裏要註意,在webpack1中使用的是babel加載,而在webpack2
中使用babel-loader加載,loader中的兩個presets的意思是,告訴Babel,編譯代碼的時候要用es2015(即ES6)和react規範來編碼
var webpack = require(‘webpack‘);
//__dirname是node.js中的一個全局變量,它指向當前執行腳本所在的目錄
module.exports = {//註意這裏是exports不是export
    // entry: [‘webpack/hot/dev-server‘, __dirname + ‘/src/main.js‘],
    entry: [‘webpack/hot/dev-server‘, __dirname + ‘/src/first.jsx‘],
    output: {//輸出目錄
        path: __dirname + "/build",//打包後的js文件存放的地方
        filename: "bundle.js"//打包後的js文件名
    },
    //webpack-dev-server配置
    devServer: {
        contentBase: ‘./build‘,//默認webpack-dev-server會為根文件夾提供本地服務器,如果想為另外一個目錄下的文件提供本地服務器,應該在這裏設置其所在目錄(本例設置到"build"目錄)
        historyApiFallback: true,//在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置為true,所有的跳轉將指向index.html
        inline: true,//設置為true,當源文件改變時會自動刷新頁面
        port: 8080//設置默認監聽端口,如果省略,默認為"8080"
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()//熱模塊替換插件
    ],
    module: {
        loaders:[
            {
                test: /\.js[x]?$/,//以js或者jsx結尾的文件
                exclude: /node_modules/,//排除node_modules文件夾下的所有文件
                loader: ‘babel-loader?presets[]=es2015&presets[]=react‘
            },
        ]
    }
};

配置完成後,cmd命令行中輸入npm run dev來啟動dev服務器來查看並且修改first.jsx文件的內容,來查看配置是否正確

如何使用webpack打包前端項目