如何使用webpack打包前端項目
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打包前端項目