webpack 本質上是一個打包工具,它會根據代碼的內容解析模塊依賴,幫助咱們把多個模塊的代碼打包。借用 webpack 官網的圖片:javascript
雖然webpack4.x的版本能夠零配置開始構建,可是在實際的項目中須要其它的一些功能,仍是須要一個配置文件。css
下面一步一步講解配置一個基本的前端開發環境過程。html
首先本身環境中安裝了有node(自帶npm)。若是你的項目中沒有package.json,那麼須要使用npm init。前端
會在項目下生成一個package.json文件,其中會有以下代碼:vue
{ "name": "test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
咱們如今來使用npm來安裝webpack,能夠做爲一個全局的命令來使用:java
npm install webpack webpack-cli -g
其中webpack-cli是使用webpack的命令行工具。在 4.x 版本以後再也不做爲 webpack 的依賴了,咱們使用時須要單獨安裝這個工具。node
更多的時候咱們是把webpack做爲項目的依賴來安裝使用的。webpack
npm install webpack webpack-cli -D
package.json文件就會多了以下配置:git
"devDependencies": { "webpack": "^4.27.1", "webpack-cli": "^3.1.2" }
咱們在package.json中添加一個npm scripts:github
代碼以下:
"scripts": { "build": "webpack --mode production" }, "devDependencies": { "webpack": "^4.27.1", "webpack-cli": "^3.1.2" }
而後咱們建立一個'./src/index.js',其中index.js中的代碼任意寫,如:
export default { a:'字符串' }
而後執行npm run build後會在項目下增長了一個dist文件夾,裏面存放了webpack構建好的main.js文件。
由於是做爲項目依賴進行安裝,因此不會有全局的命令,npm 會幫助咱們在當前項目依賴中尋找對應的命令執行,若是是全局安裝的 webpack,直接執行webpack --mode production就能夠。
webpack 的幾個重要的概念:入口,loader,plugin,輸出。
所謂入口,就是webpack的構建入口。webpack會讀取這個文件,並從它這兒開始解析依賴,而後進行打包。如上面操做,一開始webpack默認的構建入口就是'./src/index.js'。
在咱們的項目中,若是是單頁面應用,通常就只有一個入口;若是是多頁面,那麼就會配置成一個頁面一個構建入口。
入口可使用entry字段來設置,webpack支持配置多個入口進行構建打包:
module.exports = { entry: './src/index.js' } // 上述配置等同於 module.exports = { entry: { main: './src/index.js' } } // 或者配置多個入口 module.exports = { entry: { foo: './src/page-foo.js', bar: './src/page-bar.js', // ... } } // 使用數組來對多個文件進行打包 module.exports = { entry: { main: [ './src/foo.js', './src/bar.js' ] } }
最後的例子,能夠理解爲多個文件做爲一個入口,webpack 會解析兩個文件的依賴後進行打包。
webpack 中提供一種處理多種文件格式的機制,即是使用 loader。咱們能夠把 loader 理解爲是一個轉換器,負責把某種文件格式的內容轉換成 webpack 能夠支持打包的模塊。
舉個例子,好比你的入口文件index.js引入了css樣式,那麼構建的時候就須要用css-loader來處理這些.css文件,同時還須要style-loader。最終打包的結果就是把不一樣類型的文件都解析成js代碼,以便在打包後能在瀏覽器中運行。
當咱們須要使用不一樣的 loader 來解析處理不一樣類型的文件時,咱們能夠在module.rules字段下配置相關的規則,好比使用babel來轉化js代碼:
module: { // ... rules: [ { test: /\.jsx?/, // 匹配文件路徑的正則表達式,一般咱們都是匹配文件類型後綴 include: [ path.resolve(__dirname, 'src') // 指定哪些路徑下的文件須要通過 loader 處理 ], use: 'babel-loader', // 指定使用的 loader }, ], }
後面有筆記會詳細記錄下loader的使用以及怎樣開發loader。
在webpack的構建工做中,除了用loader來處理模塊代碼的轉換,剩下的工做就是用plugin來完成,下面列舉經常使用的幾個:
JS代碼壓縮配置以下:
const UglifyPlugin = require('uglifyjs-webpack-plugin') module.exports = { plugins: [ new UglifyPlugin() ], }
webpack 的輸出即指 webpack 最終構建出來的靜態文件。構建結果的文件名、路徑等都是能夠配置的,使用output字段:
module.exports = { // ... output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', }, } // 或者多個入口生成不一樣文件 module.exports = { entry: { foo: './src/foo.js', bar: './src/bar.js', }, output: { filename: '[name].js', path: __dirname + '/dist', }, } // 路徑中使用 hash,每次構建時會有一個不一樣 hash 值,避免發佈新版本時線上使用瀏覽器緩存 module.exports = { // ... output: { filename: '[name].js', path: __dirname + '/dist/[hash]', }, }
咱們剛開始構建的webpack,默認的構建結果就是'./dist/main.js'。
上面總結了幾個webpack的重要概念後,來看一個簡單的配置例子,webpack運行時默認讀取項目下的webpack.config.js文件做爲配置,那麼咱們如今就在項目下建立一個webpack.config.js文件:
const path = require('path') const UglifyPlugin = require('uglifyjs-webpack-plugin') //js壓縮插件 module.exports = { entry:'./src/index.js', output:{ path:path.resolve(__dirname,'dist'), filename:'bundle.js' }, module:{ rules:[ { test:/\.jsx?/,//匹配js,jsx文件 include:[ path.resolve(__dirname,'src') ], use:'babel-loader' } ] }, // 代碼模塊路徑解析的配置 resolve: { modules: [ "node_modules", path.resolve(__dirname, 'src') ], extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"], }, plugins:[ new UglifyPlugin() //使用uglifyjs-webpack-plugin壓縮JS代碼 //根據上面第一次的構建,你會發現webpack默認使用了JS的代碼壓縮插件 //這其實也是命令中的 --mode production的效果 ] }
當你直接運行npm run build命令的時候,會報錯Cannot find module 'uglifyjs-webpack-plugin'。這兒你須要安裝以下內容:
vue-cli 使用 webpack 模板生成的項目文件中,webpack 相關配置存放在 build 目錄下。如今的腳手架vue-cli的webpack好像仍是用的webpack3.x版本,要注意下版本區別。
咱們構建基本的前端開發環境須要作哪些事情:
下面圍繞這些要求要構建開發環境。
當咱們構建打包完成生成了JS文件,怎樣把JS文件跟html頁面相關聯呢,也就是html怎樣引入js文件。固然可使用script標籤引入js文件,可是若是打包構建的js路徑變化或者使用了hash命名,那麼直接引入js文件就不合理了,這時就須要使用html-webpack-plugin
把html-webpack-plugin安裝到項目依賴中去:
npm install html-webpack-plugin -D
首先本身按照下列目錄建立模板html文件,‘./src/assets/index.html’,html內容隨便寫,以下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>這是構建的第一個web頁面</title> </head> <body> </body> </html>
將html-webpack-plugin配置到webpack.config.js中的plugins列表中:
module.exports = { // ... plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 配置輸出文件名和路徑 template: 'assets/index.html', // 配置文件模板 }), ], }
這樣,經過 html-webpack-plugin 就能夠將咱們的頁面和構建 JS 關聯起來,這樣將會產生一個包含如下內容的文件dist/index.html。打開index.html能夠看到構建後的代碼以下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>這是構建的第一個web頁面</title> </head> <body> <script type="text/javascript" src="bundle.js"></script></body> </html>
詳細瞭解可參考文檔html-webpack-plugin, 官網提供的例子html-webpack-plugin/examples/
咱們構建CSS須要使用css-loader和style-loader。
module.exports = { module: { rules: [ // ... { test: /\.css/, include: [ path.resolve(__dirname, 'src'), ], use: [ 'style-loader', 'css-loader', ], }, ], } }
注:style-loader 和 css-loader 都是單獨的 node package,須要安裝。
咱們建立一個index.css,在index.js中引入:
import './index.css'
index.css裏面隨便編寫一段css代碼:
.title{ font-weight: bold; font-size:20px; color:red; }
模板index.html改爲以下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <div class="title">這是一個主題</div> </body> </html>
安裝style-loader與css-loader:
npm install style-loader css-loader --save-dev
如今執行npm run build,而後去看生成的index.html,效果有了,css樣式添加上了。可是並無生成css文件。
解釋下css-loader跟style-loader的做用:
和url()
等引用外部文件的聲明;若是須要單獨把 CSS 文件分離出來,咱們須要使用extract-text-webpack-plugin.
因爲webpack4.x的extract-text-webpack-plugin版本尚未發佈正式版,安裝的時候須要指定使用它的 alpha 版本:
npm install extract-text-webpack-plugin@next -D
配置:
const ExtractTextPlugin = require('extract-text-webpack-plugin') module.exports = { // ... module: { rules: [ { test: /\.css$/, // 由於這個插件須要干涉模塊轉換的內容,因此須要使用它對應的 loader use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader', }), }, ], }, plugins: [ // 引入插件,配置文件名,這裏一樣可使用 [hash] new ExtractTextPlugin('index.css'), ], }
而後就會在dist文件夾下多生成一個index.css文件。詳細可參考:extract-text-webpack-plugin
一般咱們在編寫css的時候,常用less或者sass等css預處理器,咱們以less爲例,咱們把index.css改爲index.less以下:
@fontSize:20px; .title{ font-weight: bold; font-size:@fontSize; color:red; }
安裝less-loader,官網文檔對應loader:
npm install --save-dev less-loader less
對應的配置文件修改成:
module.exports = { // ... module: { rules: [ { test: /\.less$/, // 由於這個插件須要干涉模塊轉換的內容,因此須要使用它對應的 loader use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: [ 'css-loader', 'less-loader', ], }), }, ], }, // ... }
雖然css-loader會解析樣式中用url()引用的文件路徑,可是圖片有jpg/png/gif格式,webpack處理不了,須要使用一個loader配置才行,這就用到了file-loader。
file-loader 能夠用於處理不少類型的文件,它的主要做用是直接輸出文件,把構建後的文件路徑返回。
配置以下:
module.exports = { // ... module: { rules: [ { test: /\.(png|jpg|gif)$/, use: [ { loader: 'file-loader', options: {}, }, ], }, ], }, }
安裝file-loader,官方文檔file-loader:
npm install --save-dev file-loader
我在index.js引入一張圖片:
import '../assets/a.jpg'
運行結果默認在dist目錄下生成了78414f2de9fc47d29f335727a717bc3d.jpg。默認狀況下,生成的文件的文件名就是文件內容的 MD5 哈希值並會保留所引用資源的原始擴展名。
固然也能夠配置輸出路徑,文件名稱等,以下:
{ test:/\.(jpg|png|gif)$/, use:[ { loader:'file-loader', options:{ name: '[path][name].[ext]', outputPath: 'images/' } } ] }
安裝url-loader,詳細文檔請參考官網url-loader:
url-loader功能相似於file-loader
,可是在文件大小(單位 byte)低於指定的限制時,能夠返回一個 DataURL。
npm install --save-dev url-loader
配置:
module.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/i, use: [ { loader: 'url-loader', options: { limit: 8192 } } ] } ] } }
Babel是一個讓咱們可以使用 ES 新特性的 JS 編譯工具,咱們能夠在 webpack 中配置 Babel,以便使用 ES六、ES7 標準來編寫 JS 代碼。
前面已經寫過配置了,代碼以下:
module.exports = { // ... module: { rules: [ { test: /\.jsx?/, // 支持 js 和 jsx include: [ path.resolve(__dirname, 'src'), // src 目錄下的才須要通過 babel-loader 處理 ], loader: 'babel-loader', }, ], }, }
Babel 的相關配置能夠在目錄下使用 .babelrc 文件來處理,詳細參考 Babel 官方文檔 .babelrc
咱們可使用 webpack-dev-server 在本地開啓一個簡單的靜態服務來進行開發。
安裝webpack-dev-server:
npm install webpack-dev-server --save-dev
而後添加啓動命令到 package.json 中:
"scripts": { "build": "webpack --mode production", "start": "webpack-dev-server --mode development" }
而後運行npm run start,而後就能夠訪問 http://localhost:8080/ 來查看你的頁面了。默認是訪問 index.html,若是是其餘頁面要注意訪問的 URL 是否正確。
根據上面的配置,咱們已經完成了配置一個簡單的前端開發環境,實現了:構建 HTML、CSS、JS 文件、使用 CSS 預處理器來編寫樣式、處理和壓縮圖片、使用 Babel、方便開發調試的靜態服務。下面的筆記會記錄webpack的一些細節來更好的瞭解webpack。