剛接觸webpack,在網上看了些入門的教程和資料,在此做下記錄。css
簡單說就是模塊加載器,本文不做過多的介紹。html
首先確保你的機器已經安裝了Node.js和npm(安裝方式請參考其餘相關資料)。
第一步,爲你的項目新建一個文件夾,而後輸入 npm init
,而後填寫相關問題。
這樣會爲你建立了 package.json。
第二步,接下來咱們安裝 Webpack,咱們要把它安裝在本地,輸入 npm i webpack --save-dev
到此就完成了webpack的安裝了。node
/app
main.js
component.jsreact
/build
bundle.js (自動建立)
index.htmlwebpack
package.json
webpack.config.jsweb
咱們會使用 Webpack 在咱們的 /app 裏來自動建立 bundle.js 。接下來,咱們來設置 webpack.config.js。npm
webpack.config.js文件設置json
var path = require('path'); module.exports = { entry: path.resolve(__dirname, 'app/main.js'), output: { path: path.resolve(__dirname, 'build'), filename: 'bundle.js', }, };
按上述項目目錄時,__dirname可寫爲''瀏覽器
通過上述的配置,咱們已經有了一個最簡單的配置了,下面咱們用它來編譯一個簡單的Hello World。服務器
app/component.js
'use strict'; module.exports = function () { var element = document.createElement('h1'); element.innerHTML = 'Hello world'; return element; };
app/main.js
'use strict'; var component = require('./component.js'); document.body.appendChild(component());
而後在你的命令行運行 webpack
,接着你能夠看到應用會開始編譯,一個 bundle.js 文件會這樣出如今 /build 文件夾下。
build/index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> </head> <body> <script src="bundle.js"></script> </body> </html>
咱們在index.html中引入剛纔編譯好的bundle.js,咱們能夠打開 index.html,在瀏覽器中預覽一下效果。
npm
是一個很是好用的用來編譯的指令,經過 npm
你能夠不用去擔憂項目中使用了什麼技術,你只要調用這個指令就能夠了,只要你在 package.json
中設置 scripts
的值就能夠了。
接下來咱們把編譯經過 npm run build
來執行:
把下面的內容添加到 package.json
中。
"scripts": { "build": "webpack" }
如今你能夠輸入 npm run build
就能夠編譯了。
每次編譯都須要輸入npm run build
,想必你們都不肯意,下面咱們使用webpack-dev-server
在每次文件改變後自動執行編譯。
第一步須要安裝webpack-dev-server
,在命令行中輸入 npm i webpack-dev-server --save
,安裝完成後咱們須要調整package.json
的scripts
部分去包含這個指令。
package.json
{ "scripts": { "build": "webpack", "dev": "webpack-dev-server --devtool eval --progress --colors --hot --content-base build" } }
配置完成後,咱們能夠在命令行裏運行 npm run dev
,運行的時候他會執行 dev 屬性裏的值。編譯完成後,咱們能夠訪問"http://localhost:8080" 看到效果。
上述配置頂的意義:
一、webpack-dev-server - 在 localhost:8080 創建一個 Web 服務器
三、devtool eval - 爲你的代碼建立源地址。當有任何報錯的時候可讓你更加精確地定位到文件和行號
四、progress - 顯示合併代碼進度
五、colors - 命令行中顯示顏色!
六、content-base build - 指向設置的輸出目錄
當運行 webpack-dev-server
的時候,它會監聽你的文件修改。當項目從新合併以後,會通知瀏覽器刷新。爲了可以觸發這樣的行爲,你須要把你的 index.html 放到 build/ 文件夾下,而後作這樣的修改:
build/index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> </head> <body> <script src="http://localhost:8080/webpack-dev-server.js"></script> <script src="bundle.js"></script> </body> </html>
咱們須要增長一個腳本當發生改動的時候去自動刷新應用,你須要在配置中增長一個入口點。
var path = require('path'); module.exports = { entry: ['webpack/hot/dev-server', path.resolve(__dirname, 'app/main.js')], output: { path: path.resolve(__dirname, 'build'), filename: 'bundle.js', }, };
按上述目錄時,__dirname可設置爲''
就是這樣!如今你的應用就能夠在文件修改以後自動刷新了。
Webpack 容許你使用不一樣的模塊類型,可是 「底層」必須使用同一種實現。全部的模塊能夠直接在盒外運行。
ES6 模塊
import MyModule from './MyModule.js';
CommonJS
var MyModule = require('./MyModule.js');
AMD
define(['./MyModule.js'], function (MyModule) { });
一個模塊須要用它的文件路徑來加載,看一下下面的這個結構:
--app
------modules
-----------MyModule.js
------main.js (entry point)
------utils.js
打開 main.js 而後能夠經過下面兩種方式引入 app/modules/MyModule.js
app/main.js
// ES6 import MyModule from './modules/MyModule.js'; // CommonJS var MyModule = require('./modules/MyModule.js');
最開始的 ./
是 「相對當前文件路徑」
讓咱們打開 MyModule.js 而後引入 app/utils:
app/modules/MyModule.js
// ES6 相對路徑 import utils from './../utils.js'; // ES6 絕對路徑 import utils from '/utils.js'; // CommonJS 相對路徑 var utils = require('./../utils.js'); // CommonJS 絕對路徑 var utils = require('/utils.js');
相對路徑是相對當前目錄。絕對路徑是相對入口文件,這個案例中是 main.js。
在命令行在輸入npm install react --save
component.jsx
import React from 'react'; export default class Hello extends React.Component { render() { return <h1>Hello world</h1>; } }
main.js
import React from 'react'; import Hello from './component.jsx'; main(); function main() { React.render(<Hello />, document.getElementById('app')); }
build/index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> </head> <body> <div id="app"></div> <script src="http://localhost:8080/webpack-dev-server.js"></script> <script src="bundle.js"></script> </body> </html>
爲了可以使用 JSX 語法,你須要用 Webpack 來轉碼你的 JavaScript,這是加載器的工做,咱們可使用一個很好用也有不少功能的 Babel。
npm install babel-loader --save-dev
如今咱們須要去配置 Webpack 來使用加載器。
webpack.config.js
var path = require('path'); var config = { entry: ['webpack/hot/dev-server', path.resolve('', 'app/main.js')], output: { path: path.resolve(__dirname, 'build'), filename: 'bundle.js' }, module: { loaders: [{ test: /\.jsx?$/, // 用正則來匹配文件路徑,這段意思是匹配 js 或者 jsx loader: 'babel' // 加載模塊 "babel" 是 "babel-loader" 的縮寫 }] } }; module.exports = config;
在命令行中運行 npm run dev
,而後刷新頁面就能夠看到修改。
你可能注意到在引入 React JS 到你的項目以後,給你的應用從新合併會花費太多的時間。在開發環境中,最理想的是編譯最多 200 到 800 毫秒的速度,取決於你在開發的應用。
在開發環境中使用壓縮文件
爲了避免讓 Webpack 去遍歷 React JS 及其依賴,你能夠在開發中重寫它的行爲。
webpack.config.js
var path = require('path'); var node_modules = path.resolve(__dirname, 'node_modules'); var pathToReact = path.resolve(node_modules, 'react/dist/react.min.js'); config = { entry: ['webpack/hot/dev-server', path.resolve(__dirname, 'app/main.js')], resolve: { alias: { 'react': pathToReact } }, output: { path: path.resolve(__dirname, 'build'), filename: 'bundle.js', }, module: { loaders: [{ test: /\.jsx?$/, loader: 'babel' }], noParse: [pathToReact] } }; module.exports = config;
咱們在配置中作了兩件事:
一、無論 「React」 是何時在代碼中引入的,它會去匹配壓縮後的 React JS 文件取代去 node_modules 中遍歷。
二、無論 Webpack 何時試圖是解析壓縮文件,咱們阻止它,告訴它那不是必須的。
Webpack容許像加載任何代碼同樣加載 CSS。你能夠選擇你所須要的方式,可是你能夠爲每一個組件把全部你的 CSS 加載到入口主文件中來作任何事情。
加載 CSS 須要 css-loader 和 style-loader,他們作兩件不一樣的事情,css-loader會遍歷 CSS 文件,而後找到 url() 表達式而後處理他們,style-loader 會把原來的 CSS 代碼插入頁面中的一個 style 標籤中。
安裝加載器
在命令行中輸入npm install css-loader style-loader --save-dev
安裝完畢後能夠將加載器配置到 Webpack.config.js 文件中。
webpack.config.js
var path = require('path'); var config = { entry: ['webpack/hot/dev-server', path.resolve(__dirname, 'app/main.js')], output: { path: path.resolve(__dirname, 'build'), filename: 'bundle.js' }, module: { loaders: [{ test: /\.jsx$/, loader: 'jsx' }, { test: /\.css$/, // Only .css files loader: 'style!css' // Run both loaders }] } }; module.exports = config;
加載 CSS 文件
加載一個 CSS 文件就和加載其餘文件同樣:
main.js
import './main.css'; // Other code
Component.jsx
import './Component.css'; import React from 'react'; export default React.createClass({ render: function () { return <h1>Hello world!</h1> } });
將全部CSS合併成一個
在你的主入口文件中個,好比 app/main.js 你能夠爲整個項目加載全部的 CSS:
app/main.js
import './project-styles.css'; // 其餘 JS 代碼
CSS 就徹底包含在合併的應用中,不再須要從新下載。
若是你想發揮應用中多重入口文件的優點,你能夠在每一個入口點包含各自的 CSS:
app/main.js
import './style.css'; // 其餘 JS 代碼
app/entryA/main.js
import './style.css'; // 其餘 JS 代碼
app/entryB/main.js
import './style.css'; // 其餘 JS 代碼
你把你的模塊用文件夾分離,每一個文件夾有各自的 CSS 和 JavaScript 文件。再次,當應用發佈的時候,導入的 CSS 已經加載到每一個入口文件中。
具體的組件
你能夠根據這個策略爲每一個組件建立 CSS 文件,可讓組件名和 CSS 中的 class 使用一個命名空間,來避免一個組件中的一些 class 干擾到另一些組件的 class
app/components/MyComponent.css
.MyComponent-wrapper { background-color: #EEE; }
app/components/MyComponent.jsx
import './MyComponent.css'; import React from 'react'; export default React.createClass({ render: function () { return ( <div className="MyComponent-wrapper"> <h1>Hello world</h1> </div> ) } });
使用內聯樣式取代 CSS 文件
在 「React Native」 中你再也不須要使用任何 CSS 文件,你只須要使用 style 屬性,能夠把你的 CSS 定義成一個對象,那樣就能夠根據你的項目從新來考略你的 CSS 策略。
app/components/MyComponent.jsx
import React from 'react'; var style = { backgroundColor: '#EEE' }; export default React.createClass({ render: function () { return ( <div style={style}> <h1>Hello world</h1> </div> ) } });