webapck構(gòu)建react開發(fā)環(huán)境(一)

什么是webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

戈德斯文版譯文:webpack是一個模塊打包器。它的主要目的是將JavaScript文件打包以便在瀏覽器中使用,并且它也能夠轉(zhuǎn)換查排、打包或構(gòu)建任何資源或數(shù)據(jù)虐杯。

webpack的理念

webpack的宗旨就是把所用用的JavaScript還是css唱较,或者是圖片晾蜘,甚至各類預(yù)編譯器、js的超集語言鼓鲁,都直接打包成最純粹的js邮辽、css唠雕、jpg和png。 在前端工程化吨述,自動化的路上插了好多路燈岩睁。

Webpack與Gulp、Grunt區(qū)別

Gulp和Grunt的工作方式是在一個配置文件中寫好對某一類文件進(jìn)行某種或幾種操作揣云,然后可以自動幫你轉(zhuǎn)換捕儒、壓縮等一系列操作,在自動化有一定的幫助。

而webpack則是在自動化處理各類文件刘莹、資源上以后阎毅,會把整個項目當(dāng)成一個整體,從一個入口文件点弯,把所有依賴到的資源都進(jìn)行整合處理扇调,打包。使用webpack抢肛,能真正體會到JavaScript的發(fā)展方向——模塊化狼钮。提高了開發(fā)效率,降低了維護(hù)成本捡絮。

初始化項目

$ mkdir webpack-demo
$ cd webpack-demo
$ npm init

如沒有特殊需求熬芜,一路回車就完事了,生成package.json的文件锦援。

安裝webpack

$ npm install -g webpack webpack-cli
$ npm install webpack --save-dev

構(gòu)建項目目錄

在項目跟目錄下執(zhí)行

$ mkdir src              // 創(chuàng)建源代碼目錄
$ mkdir public         // 創(chuàng)建公共模板目錄
$ cd src                  // 進(jìn)入源代碼目錄
$ mkdir  components          // 創(chuàng)建組件目錄
$ touch index.js          // 創(chuàng)建項目入口文件
$ touch App.js            // 創(chuàng)建App組件
$ cd ../public                   // 回到項目跟目錄猛蔽,進(jìn)入公共模板目錄
$ touch index.html        // 創(chuàng)建公共模板文件
$ cd ..                        // 返回跟目錄
$ mkdir dev                // 創(chuàng)建開發(fā)目錄
$ mkdir dist                // 創(chuàng)建生產(chǎn)目錄
$ touch webpack.config.dev.js            // 創(chuàng)建開發(fā)環(huán)境webpack配置文件
$ touch webpack.config.prod.js            // 創(chuàng)建生產(chǎn)環(huán)境webpack配置文件

最后的目錄結(jié)構(gòu)


目錄結(jié)構(gòu).png

webpack配置

寫入最基本的webpack
webpack.config.dev.js

const path = require('path');

module.exports = {
  /* 輸入配置 */
  entry: {
    app: './src/index.js'            /* 設(shè)置項目入口路徑 */
  },
  mode: 'development',        /* 配置打包環(huán)境為開發(fā)環(huán)境 */
  /* 輸出配置 */
  output: {
    path: path.resolve(__dirname, './dev'),        /* 配置輸出路徑 */
    filename: 'bundle.min.js',                             /* 配置輸出名稱 */
  },
};

為了更方便的在命令行中執(zhí)行webpack打包命令剥悟,我們在package.json寫上

{
  "scripts": {
    "start": "webpack --config webpack.config.dev.js"
  }
}

這樣在命令行中輸入npm run start就可以執(zhí)行根據(jù)webpack.config.dev.js的webpack打包過程了灵寺。
如果想要動態(tài)監(jiān)聽文件變化需要在命令后面添加 --watch。

引入react

安裝react

$ npm install react react-dom

安裝好以后在./src/index.js寫上

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDom.render(<App />, document.getElementById('root'));

然后在./src/App.js中寫

import React from 'react';
import './App.less';

const App = () => (
  <div>首頁</div>
);

export default App;

因為只是demo区岗,沒有寫任何方法和生命周期函數(shù)略板,所以寫的無狀態(tài)組件
最后在./public/index.html寫上模板,主要是寫一個id為root的div

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>webpack react</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>

loader

webpack單單自己是不能對各種資源進(jìn)行處理的慈缔,所以要借用各種loader來進(jìn)行資源處理

css-loader叮称、style-loader和less-loader

我們先來配置處理css文件的loader,直接加上處理預(yù)編譯器less的loader
首先藐鹤,安裝各種這三個loader瓤檐,并且安裝less,如果你使用的sass或者stylus娱节,可以安裝對應(yīng)的預(yù)編譯器和loader

$ npm install less less-loader css-loader style-loader --save-dev

安裝完以后進(jìn)行在webpack.config.dev.js中用上他們

const path = require('path');

module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.(css|less)$/,
        use: ['style-loader', 'css-loader', 'less-loader'],
        include: path.resolve('./src'),
      },
    ]
  }
  ...
};

這樣就不會有問題了挠蛉,注意!肄满!loader的順序一定不要搞錯谴古,因為loader是按從最后一個往前處理的,先用less-loader處理稠歉,最后用style-loader處理掰担。

url-loader

處理靜態(tài)文件,安裝

 $ npm install url-loader

配置webpack.config.dev.js

const path = require('path');

module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.(css|less)$/,
        use: ['style-loader', 'css-loader', 'less-loader'],
        include: path.resolve('./src'),
      },
      {
        test: /\.(png|jpg|jpeg)$/,
        use: 'url-loader?limit=8192&name=images/[name].[hash].[ext]',
        include: path.resolve('./src'),
      },
    ]
  }
  ...
};

limit: 表示超過多少就使用base64來代替怒炸,單位是byte
name:可以設(shè)置圖片的路徑带饱,名稱和是否使用hash

babel,處理react語法和es新語法

babel是什么呢阅羹?纠炮?月趟?

babel.png

這是官方解釋,意思是babel是一個javascript的編譯器恢口,可以讓你在現(xiàn)在用上下一代javascript孝宗。眾所周知,現(xiàn)在瀏覽器各自執(zhí)行的標(biāo)準(zhǔn)并不是很統(tǒng)一耕肩,版本不同因妇,支持的javascript的語法也不同,babel就是幫助我們把我們寫出來的新興javascript語法轉(zhuǎn)換成配置的瀏覽器版本可以識別的語法猿诸。具體的可以看Babel官網(wǎng)Can i use官網(wǎng)

安裝babel和babel-loader

$ npm install babel-core babel-loader --save-dev

配置webpack.config.dev.js

const path = require('path');

module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.(css|less)$/,
        use: ['style-loader', 'css-loader', 'less-loader'],
        include: path.resolve('./src'),
      },
      {
        test: /\.(png|jpg|jpeg)$/,
        use: 'url-loader?limit=8192&name=images/[name].[hash].[ext]',
        include: path.resolve('./src'),
      },
      {
        test: /\.(js|jsx)$/,
        use: [
          {
            loader: 'babel-loader',
          },
        ],
        include: path.resolve('./src'),
      },
    ]
  }
  ...
};

如果這個時候你執(zhí)行一下npm run start婚被,會發(fā)現(xiàn)報錯

報錯.png

提示我們?nèi)绻胋abel-loader@8的話,必須用babel的7版本以上梳虽,就是babel-core必須是7以上址芯,我們看一下我們的package.json
package.json.png

看問題就出在這里,所以我們需要重新安裝babel-loader窜觉,以搭配對應(yīng)的babel-core

$ npm install babel-loader@7

這樣我們就可以執(zhí)行npm run start
目前我還不知道babel的版本有什么區(qū)別谷炸,可以立個TODO,有空可以具體看一下babel的版本區(qū)別
現(xiàn)在我們還需要告訴babel我們用的是什么語法禀挫,在根目錄創(chuàng)建.babelrc旬陡,其實我們把接下來的配置寫在webpack.config.dev.js里也是可以的

$ touch .babelrc

并且在.babelrc中寫入

{
  "presets": [
    "es2015",
    "react"
  ]
}

并且安裝對應(yīng)的處理插件

$ npm install babel-preset-es2015 babel-preset-react

使用HtmlWebpackPlugin插件

在我們之前打包后的目錄下只有一個js文件,而我們需要手動在./public/index.html中引用才能起作用语婴,現(xiàn)在描孟,HtmlWebpackPlugin就是幫我們把打包后的js和html一起生成。這就是為什么稱./public/index.html為模板的原因砰左。

安裝
$ npm install html-webpack-plugin
配置
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  ...
  plugins: [
    new HtmlWebpackPlugin({
      filename: path.resolve('./dev', 'index.html'),
      template: path.resolve('./public', 'index.html'),
    })
  ]
};

現(xiàn)在執(zhí)行npm run start以后匿醒,./dev下面就會有一個js文件一個html文件,并且html里面已經(jīng)引用好了js

使用webpack-dev-server熱更新

現(xiàn)在有一種情況就是缠导,每次我們更改完文件廉羔,需要手動打包,然后手動刷新頁面酬核,就算我們用--watch蜜另,還是會需要手動刷新頁面,才能看到我們更改后的樣子嫡意,現(xiàn)在有了webpack-dev-server举瑰,就省去了我們手動刷新頁面,并且是基于node在本地起一個服務(wù)以便于讓我們的代碼更真實的從服務(wù)器返回的場景蔬螟,而不是手動雙擊html文件了此迅。

安裝

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

更改package.json中的start命令

 {
  "scripts": {
    "start": "webpack-dev-server --config webpack.config.dev.js"
  }
}

更改webapck.config.dev.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  ...
  devServer: {
    "contentBase": './dev',
    "compress": true,
  },
};

contentBase:表示server文件的根目錄
compress:表示開啟gzip
webpack-dev-server默認(rèn)情況下會將output的內(nèi)容放在內(nèi)存中,是看不到物理的文件的,如果想看到文件耸序,需要下載另一個插件忍些。
這個時候如果你執(zhí)行了npm run start,會看到如下畫

webapck-dev-server.png

從圖上我們可以看到坎怪,webpack-dev-server幫我們在本地8080端口起了一個服務(wù)罢坝,并且直接訪問./dev目錄

模塊熱替換(Hot Module Replacement)

模塊熱替換(Hot Module Replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允許在運行時更新各種模塊搅窿,webpack-dev-server雖然手動刷新頁面變成了自動刷新嘁酿,但是!男应!但是D炙尽!模塊熱替換可以把刷新都省了沐飘,頁面直接變游桩。

配置

更改webpack.config.dev.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');

module.exports = {
  ...
  devServer: {
    contentBase: './dev',
    compress: true,
    hot: true,
  },

  plugins: [
    new HtmlWebpackPlugin({
      filename: path.resolve('./dev', 'index.html'),
      template: path.resolve('./public', 'index.html'),
    }),
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  ],
};

安裝react-hot-loader

$ npm install react-hot-loader

并在src目錄下新建Container.js

import React from 'react';
import { hot } from 'react-hot-loader';
import App from './App';

const Container = () => (
  <App />
);
export default hot(module)(Container);

更改./src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Container from './Container';

ReactDOM.render(<Container />, document.getElementById('root'));

更改webpack.config.dev.js

{
   "scripts": {
    "start": "webpack --config webpack.config.dev.js"
  }
}

執(zhí)行npm run start,更改代碼保存耐朴,會發(fā)現(xiàn)頁面不會刷新借卧,但是內(nèi)容會改變,css自帶熱模塊替換隔箍,所以現(xiàn)在更改js和css谓娃,頁面都會自己的更替新的內(nèi)容

到這脚乡,用webpack構(gòu)建一個react開發(fā)環(huán)境已經(jīng)完成

啟用eslint

再說一下eslint蜒滩,沒有規(guī)矩,不成方圓奶稠,國有國法俯艰,家有家規(guī)。寫代碼自然也要遵守一定的規(guī)范锌订,當(dāng)然竹握,不遵守規(guī)范代碼也是可以跑通,但是在后期維護(hù)和易讀性上辆飘,肯定沒有按著一定規(guī)范寫出來的代碼好看啦辐。所以可以采用用eslint來進(jìn)行代碼規(guī)范檢查,并且選用airbnb這家公司的規(guī)范蜈项。


airbnb.png

安裝

$ npm install -g eslint          // 全局安裝eslint
$ eslint --init                        // 在項目跟目錄進(jìn)行eslint初始化芹关,并根據(jù)選擇,選擇airbnb規(guī)范

并且在自己的編輯器上配好eslint紧卒,該裝插件裝插件侥衬,該改設(shè)置改設(shè)置

結(jié)尾

在這我只是簡單的建了一個開發(fā)環(huán)境,生產(chǎn)環(huán)境有時間再出一個,對于各個loader還有很多的options可以設(shè)置轴总,webpack還有很多的插件都沒有涉及直颅,什么代碼分離,tree-shaking都沒有講到怀樟,大家可以自己查看webpack的相關(guān)文檔功偿,真的很有幫助。
加油往堡!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脖含,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子投蝉,更是在濱河造成了極大的恐慌养葵,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘩缆,死亡現(xiàn)場離奇詭異关拒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)庸娱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門着绊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人熟尉,你說我怎么就攤上這事归露。” “怎么了斤儿?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵剧包,是天一觀的道長。 經(jīng)常有香客問我往果,道長疆液,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任陕贮,我火速辦了婚禮堕油,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肮之。我一直安慰自己掉缺,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布戈擒。 她就那樣靜靜地躺著眶明,像睡著了一般。 火紅的嫁衣襯著肌膚如雪峦甩。 梳的紋絲不亂的頭發(fā)上赘来,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天现喳,我揣著相機(jī)與錄音,去河邊找鬼犬辰。 笑死嗦篱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的幌缝。 我是一名探鬼主播灸促,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼涵卵!你這毒婦竟也來了浴栽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤轿偎,失蹤者是張志新(化名)和其女友劉穎典鸡,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坏晦,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡萝玷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了昆婿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片球碉。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仓蛆,靈堂內(nèi)的尸體忽然破棺而出睁冬,到底是詐尸還是另有隱情,我是刑警寧澤看疙,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布豆拨,位于F島的核電站,受9級特大地震影響狼荞,放射性物質(zhì)發(fā)生泄漏辽装。R本人自食惡果不足惜帮碰,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一相味、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧殉挽,春花似錦丰涉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至傻唾,卻和暖如春投慈,著一層夾襖步出監(jiān)牢的瞬間承耿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工伪煤, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留加袋,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓抱既,卻偏偏與公主長得像职烧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子防泵,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1 Webpack 1.1 概念簡介 1.1.1 WebPack是什么 1蚀之、一個打包工具 2弧可、一個模塊加載工具 3...
    Kevin_Junbaozi閱讀 6,659評論 0 16
  • 寫在前面的話 閱讀本文之前指攒,先看下面這個webpack的配置文件,如果每一項你都懂捕发,那本文能帶給你的收獲也許就比較...
    不忘初心_9a16閱讀 3,234評論 0 17
  • 版權(quán)聲明:本文為博主原創(chuàng)文章贱纠,未經(jīng)博主允許不得轉(zhuǎn)載。 webpack介紹和使用 一响蕴、webpack介紹 1谆焊、由來 ...
    it筱竹閱讀 11,119評論 0 21
  • 不貴于無過而貴于能改過∑忠模——王守仁 也就是說辖试,我們不怕犯錯,就怕認(rèn)識不到自己的錯誤劈狐,知錯能改罐孝,及時改正,邊做邊學(xué)邊...
    75372b9f700e閱讀 933評論 1 5
  • 看著簡書里的簡書包肥缔,突然想起小時候父親給我們包書皮的時刻莲兢。不知道是不是長大了,一個人在外求學(xué)续膳,一些偶爾的場景老...
    記憶拾光閱讀 462評論 0 2