隨着前端項目複雜程度愈來愈高,依賴也愈來愈多,爲了提升項目中代碼的可複用性,前端開始提出模塊化開發的思路,前端模塊化會有如下幾個痛點:javascript
命名衝突
文件依賴
代碼複用
模塊化,會將相關的代碼封裝成一個package包的文件,當須要的時候,直接拿來用便可(import引入)。至於相關文件的直接依賴如何處理,webpack會幫咱們解決這個問題。那麼模塊化應該使用什麼樣的規範呢?常見的模塊化的標準主要以下:php
commonjscss
nodejs使用的就是commonJs的規範,採用的同步方式加載依賴,一個文件就是一個模塊。html
導入導出方式以下:前端
導入:const aa = require('./aa') 導出:module.exports = aa.fun
缺點是加載的模塊是同步的,只有加載完才能執行後面的操做。由於 node.js 的模塊文件通常存在於本地硬盤,因此通常不會出現這個問題,可是在瀏覽器環境該規範就不那麼適用了。java
AMDnode
由於commonJS不適用於瀏覽器的環境,因此出現AMD規範。特色: 異步加載/推崇依賴前置、提早執行 。require.js最佳實踐react
使用方式:webpack
定義模塊: define()
加載模塊:require() 引用:require.config()
CMD的使用方式如上,可是特色不太同樣。CMD是異步加載/依賴就近、延遲執行 sea.js最佳實踐nginx
ES6
ES6 直接在語言層面上實現了模塊化。咱們如今用的最多的就是 ES6 模塊化的實踐方式。
導入導出方式以下:
導入:
import aa from 'aa' import {A} from 'aa' 導出: export default {A, B} export {A, B} export funtion aa() {}
雖然ES6是模塊化的最終方案,可是仍是在許多瀏覽器上有兼容問題,須要對代碼進行轉碼處理才行。
樣式文件中的模塊化
前端開發中,樣式文件也開始支持模塊化,以stylus爲例,一般將一些通用的文件放到文件中,在使用相關的樣式時,直接@import引入文件,就能使用對應的代碼片斷,固然也能定義一些全局的參數(顏色,圓角類)進行使用。
// common.styl .center-transform top 50% left 50% transform translate(-50% -50%) center-transform() top 50% left 50% transform translate(-50% -50%) // 使用 @import 'common.styl' .box { center-transform }
首先建立一下的目錄結構:
.
├── src
│ ├── assemble
│ │ ├── css
│ │ │ ├── index.css
│ │ ├── index.html
│ │ └── js
│ │ ├── index.js
│ │ └── test.js
│ ├── babyTest
│ │ ├── css
│ │ │ └── index.css
│ │ ├── index.html
│ │ └── js
│ │ └── index.js
文件內容:
// 1. assemble-index.html: <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title></title> </head> <body> </body> </html> // 2. assemble-css/index.css: body {background: red} // 3. assemble-js/index.js: import '../css/index.css' console.log('index.js') // 4. assemble-js/test.js: console.log('test.js') babyTest目錄和上面相似
建立webpack.config.js文件,下面直接配置的是多文件入口:
// 引入插件 const HtmlWebpackPlugin = require('html-webpack-plugin') // 相關配置 module.exports = { mode: 'development', // 指定webpack的模式 entry: { 'assemble/js/index': './src/assemble/js/index.js', 'assemble/js/test': './src/assemble/js/test.js', 'babyTest/js/index': './src/babyTest/js/index.js' }, output: { filename: '[name].js', // 打包後輸出文件的文件名 path: path.resolve('./output/market') // 打包後的文件存放的地方 }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/assemble/index.html', filename: 'assemble/index.html', chunks: ['assemble/js/index'] }), new HtmlWebpackPlugin({ template: './src/babyTest/index.html', filename: 'babyTest/index.html', hash: true, chunks: ['babyTest/js/index'] }) ] }
上面寫的實例中,將loader和plugins已經使用了,能夠先按照上面的使用,後邊將進行詳細方法的介紹。
使用前,安裝對應的依賴包
npm install css-loader style-loader html-webpack-plugin -D
能夠看到在根目錄下有output目錄,裏面就行對應的打包文件。直接運行output文件下的目錄,可以看到對應效果,css和js都可以執行成功。
備註:執行打包命令的方式有如下幾種方式
node_modules/.bin/webpackwebpack在package.json文件中配置對應的命令 "scripts": { "start": "webpack"}
入口起點(entry point)指示 webpack 應該使用哪一個模塊,來做爲構建其內部依賴圖的開始。進入入口起點後,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。
每一個依賴項隨即被處理,最後輸出到稱之爲 bundles 的文件中,,entry屬性 來指定一個入口起點(或多個入口起點)。默認值爲 ./src。
output 屬性告訴 webpack 在哪裏輸出它所建立的 bundles,以及如何命名這些文件,默認值爲 ./dist。基本上,整個應用程序結構,都會被編譯到你指定的輸出路徑的文件夾中。
loader 用於對模塊的源代碼進行轉換。loader 可使你在 import 或"加載"模塊時預處理文件。所以,loader 相似於其餘構建工具中「任務(task)」,並提供了處理前端構建步驟的強大方法。loader 能夠將文件從不一樣的語言(如 TypeScript)轉換爲 JavaScript,或將內聯圖像轉換爲 data URL。loader 甚至容許你直接在 JavaScript 模塊中 import CSS文件!
上面的配置中就用到了 css-loader和style-loader,主要是在對引用的css文件會用style-loader和css-loader進行處理,當配置多個loader的時候,按照從左至右的方式進行處理。
Loaders的配置主要包含如下配置:
Babel是一個編譯JavaScript的平臺,能夠幫咱們將編譯的代碼
Babel實際上是幾個模塊化的包,其核心功能稱爲babel-core的npm包中,webpack能夠把其不一樣的包整合在一塊兒使用,對於每個你須要的功能或拓展,你都須要安裝單獨的包(用的最多的就是解析ES6語法的包 babel-preset-env)
npm install --save-dev babel-core babel-loader babel-preset-env
在webpack.config.js中,module的rules中添加;
{
test: /\.js$/, use: { loader: 'babel-loader', options: { presets: [ 'env', 'react' ] } }, include: /src/, exclude: /node_modules/ }
Babel的配置能夠直接在webpack.config.js中進行配置,可是有時配置項過多,但在這個文件中配置過多js編譯規則的代碼,顯得可讀性不太好,所以支持在.babelrc中單獨配置,webpack會自動調用這個文件中的配置項。
// .babelrc文件 { "presets": ["react", "env"] }
loader name | 介紹 |
---|---|
css-loader | 解析@import 和 Url()引用的css文件,轉化成 import/require() 的方式而後在解析他們 |
style-loader | 將 CSS 放在 <style></style> 標籤中注入到 DOM 中 |
sass-loader | 將 SASS/SCSS 轉換爲 css |
less-loader | 將 less 轉化爲 css |
html-loader | 將 html 輸出爲字符串,也能夠根據配置進行壓縮 |
babel-loader | 加載 ES2015+ 代碼,而後使用 Babel 轉譯爲 ES5 |
url-loader | 將文件加載爲 Base64 編碼的 URL |
file-loader | 能夠解析項目中的url引入(不只限於css),根據咱們的配置 |
插件是 webpack 的支柱功能。webpack 自身也是構建於,你在 webpack 配置中用到的相同的插件系統之上!插件目的在於解決 loader 沒法實現的其餘事。
Plugins在構建的過程當中,經過在構建流程中注入對應的鉤子,給webpack帶來很大的靈活性。
Loaders和Plugins經常被弄混,可是他們實際上是徹底不一樣的東西,能夠這麼來講,loaders是在打包構建過程當中用來處理源文件的(JSX,Scss,Less..),一次處理一個,Plugins並不直接操做單個文件,它直接對整個構建過程其做用
上面的實例中就使用了html-webpack-plugin插件,主要的功能就是自動引用使用的js文件,使用css的話,也會根據必定規則進行動態插入,在控制檯查看文件代碼時,能夠看到引用的css文件,會自動插在<head></head>之間。如截圖所示
咱們能夠根據本身的項目構建方式,使用對應的插件,就不一一舉例說明了。
Plugins name | 介紹 |
---|---|
HtmlWebpackPlugin | 簡單建立 HTML 文件,用於服務器訪問 |
clean-webpack-plugin | 刪除指定的文件夾 |
webpack-bundle-analyzer | webpack打包體積查看,便於優化文件體積 |
speed-measure-webpack-plugin | 查看測量出在你的構建過程當中,每個 Loader 和 Plugin 的執行時長(優化webpack時能幫你看出對應的時間) |
啓動一個靜態服務器,默認會自動刷新,就是說你對html,css,js文件作了修改並保存後,瀏覽器會默認刷新一次展示修改後的效果
正常狀況下咱們都是在開發環境中開發項目,因此以前配置的腳本"dev"能夠派上用場了,在執行npm run dev命令後,會啓動靜態服務器,咱們訪問localhost:3000端口就能夠看到開發的頁面內容了
對應的配置文件:
// webpack.config.js的配置文件 devServer: { host: 'localhost', // 默認是localhost port: '3000', // 端口 open: true, // 自動打開 hot: true, // 開啓熱更新 openPage: 'assemble' // 默認打開的文件 } // package.json中的配置 "scripts": { "dev": "webpack-dev-server --open" }
一般本地開發,測試和線上的構建方式略微有點區別,線上文件都會將文件中的空行,空格,換行清除,而且壓縮html,css,js和對應image的體積,這樣就能保證體積最小,加快頁面的加載速度。
可是開發和測試環境一般,在瀏覽器中,沒法對代碼逐行打斷點進行調試,全部須要使用source maps進行調試,它使得咱們在瀏覽器中能夠看到源代碼,進而逐行打斷點調試。
在webpack.config.js文件中,添加devtool屬性,賦值爲 source-map或者inline-source-map便可,後者報錯信息更加具體,會指示源代碼中的具體錯誤位置,而source-map選項沒法指示到源代碼中的具體位置。
廣州品牌設計公司https://www.houdianzi.com PPT模板下載大全https://redbox.wode007.com
問題描述:更改一個文件,致使全部的文件都會從新進行編譯。
優化方案:使用緩存