摘要:否則可能會導致全局安裝的版本與項目中的配置文件可能存在不匹配。是一個流行的插件,其作用是為中的屬性添加瀏覽器特定的前綴。插件允許開發人員在當前的項目中使用將來版本中可能會加入的新特性。
本文webpack是在Mac平臺下基于官方最新版本v3.10,對于webpack@v2會有小的差異,待全文完成后會補充webpack@v2與v3版本之間的差異使用webpack前的準備 1、初始化一個前端項目
為了方便之后自己更好的使用這個webpack_starter,引入git的支持,一是可以把一些通用的東西放在主分支,二是可以把后面不同的配置支持可以通過branch或者tag的方式分門別類。
在github初始化一個webpack_starter項目,如下圖所示,初始化.gitignore支持Node語言
#clone項目到本地 git clone https://github.com/mpandar/webpack_starter.git cd webpack_starter
利用yarn初始化項目(當然同樣可以使用npm,無太大差異,此處不再補充npm使用方法)
初始化過程按照提示完成即可,唯一注意的是entry point,這是webpack進行打包時的入口文件,默認是根目錄下的index.js,不過通常情況下,我們的源碼都是在src目錄下,所以修改為src/index.js
> yarn init yarn init v1.3.2 question name (webpack_starter): question version (1.0.0): 0.1.0 question description: a webpack start project question entry point (index.js): src/index.js question repository url (https://github.com/mpandar/webpack_starter.git): question author (mpandar2、安裝webpack): question license (MIT): question private: success Saved package.json ? Done in 53.55s.
多帶帶安裝與全局安裝對于webpack的使用并無太大差異,但推薦即使全局安裝以后,仍要在項目中進行多帶帶的安裝,方便項目移植。否則可能會導致全局安裝的webpack版本與項目中的配置文件可能存在不匹配。當然多帶帶安裝后,使用一些npm或yarn命令,它們會優先使用本地安裝的webpack
#全局安裝 yarn global add webpack #單項目使用 yarn add webpack3、初始化項目目錄
|--- |--dist //存放webpack打包后相關文件 |--src //存放項目源碼 |--index.js |--config //項目相關的配置文件 |--webpack.config.js //webpack默認讀取項目根目錄下的webpack.config.js文件作為配置信息,為了規范化移入到config目錄下 |--package.json了解webpack配置文件webpack.config.js
當然,即使沒有配置文件,直接運行webpack命令,同樣可以直接對js文件完成打包工作,這里是一篇分析webpack打包后的代碼的文章:簡要分析webpack打包后代碼,其中用到的一個新命令npx,很簡單,介紹點這里
#直接打包 npx webpack src/index.js dist/bundle.js
為了應對更靈活的使用場景,webpack支持配置文件,并且默認情況下,在項目根目錄下,如果存在webpack.config.js文件,那么webpack會主動讀取該文件作為配置內容,不過Demo下,為了更加符合我們的目錄規范,我們將config文件移到了config目錄下
//當配置文件內容為空時,運行該命令會提示`Configuration file found but no entry configured` npx webpack src/index.js --config config/webpack.config.js
接下來,讓我們看一下一個webpack配置文件,最簡單只需要包含entry(定義入口文件)和output(定義打包輸出文件)這兩個部分:
const path = require("path"); const base = path.join(__dirname, "..") module.exports = { entry: path.resolve(base, "src", "index.js"), output: { filename: "bundle.js", path: path.resolve(base, "dist") } };
注:使用path模塊只是為了代碼清晰,你完全可以不用,直接用__dirname+"/../src"類似代碼拼接
//這樣就不需要在命令行定義輸入輸出文件啦 npx webpack --config config/webpack.config.js
除了entry和output,webpack中最常見的就是module、resolve、plugins,大致結構如下:
module.exports = { entry: path.resolve(base, "src", "index.js"), output: { filename: "bundle.js", path: path.resolve(base, "dist") }, devtool: "eval-source-map", devServer: { contentBase: path.resolve(base, "dist"), historyApiFallback: true, inline: true, proxy: { "/api": "http://localhost:8000" } }, module: { rules: [ ] }, resolve: { }, plugins: [ ] };
當然了解webpack最好的地方永遠是官方文檔,傳送門,接下來,自然是在目前配置的基礎上,增添更多令人興奮的特性
為開發增加更多利器 生成Source Map,為調試助力開發離不開調試,但經過編碼后的代碼并不利于調試,很找到出錯的地方對應的你寫的代碼,而Source Maps就是來幫我們解決這個問題的。
而webpack支持Source Maps僅僅是增加一行 devtool 配置選項,具體配置選項可以看這里的官方文檔,其中兩個選項 eval-source-map 與 source-map 是比較常用的選項,前一個選項推薦僅僅用在開發環境,而后一個通常在一些第三方庫中,提供給開發者調試使用。當然對于任何上線項目,實際上都推薦使用*.min.js并不使用Source Map以加快網絡加載。
module.exports = { entry: path.resolve(base, "src", "index.js"), output: { filename: "bundle.js", path: path.resolve(base, "dist") }, devtool: "eval-source-map" }自動監控代碼更新,自動編譯,自動瀏覽器刷新
作為開發者,總不希望把時間浪費在執行命令和刷新頁面上,webpack提供一個多帶帶的組件webpack-dev-server為我們提供一個基于nodejs的本地服務器、文件修改監控及編譯以及瀏覽器自動刷新等特性。
首先是安裝:
yarn add webpack-dev-server --dev
詳細配置參數可查閱官方文檔,常使用參數如下:
contentBase 指定項目根目錄
historyApiFallback 主要應用在單頁應用的開發場景,它依賴于HTML5 history API,如果設置為true,所有的跳轉將指向index.html
inline 主要是解決了自動瀏覽器自動刷新問題
lazy 默認為false,若開啟后,則webpack-dev-server不再監測文件變化自動編譯,只有等到我們手動刷新瀏覽器的時候才會編譯文件
proxy 可以有效的解決開發階段的跨域問題,畢竟不是所有的前端項目,都有獨立的nodejs作為中間件去請求服務,更多的還是把前端項目編譯后與后端服務部署在一起。而開發階段又相對獨立,這時候就可以利用proxy將前端請求轉發到后端測試服務器,不影響開發
module.exports = { entry: path.resolve(base, "src", "index.js"), output: { filename: "bundle.js", path: path.resolve(base, "dist") }, devtool: "eval-source-map", devServer: { contentBase: path.resolve(base, "dist"), historyApiFallback: true, inline: true, proxy: { "/api": "http://localhost:8000" } } }
小插曲,本來測試proxy的時候,自己利用php -S localhost:8000快速起了一個監聽進程,但是訪問前端的時候卻提示轉發去請求被拒絕,后來發現webpack-dev-server去轉發請求的時候是把localhost轉化為了地址,即127.0.0.1:8000,所以在php啟動監聽進程時候,需要使用php -S 127.0.0.1:8000或者php -S 0.0.0.0:8000監聽所有網卡地址
webpack-dev-server的使用同webpack基本運行一樣,只是webpack-dev-server是一個不會退出的進程,并自動監控文件變化等(Ctrl+C退出)
npx webpack-dev-server --config config/webpack.config.js更方便的打包命令
使用npx webpack --config config/webpack.config.js進行打包實際上已經很方便了,但是當我們需要又有開發環境的配置,又有生產環境的配置,甚至還要為命令增加其他的環境變量的時候,這個命令簡直是又臭又長,我們總不能每次都輸入這個繁瑣的命令,其實我們可以利用npm scripts,這里是一篇阮一峰大神對npm腳本的介紹
//package.json { "scripts": { "build": "webpack --config config/webpack.config.js", "dev": "webpack-dev-server --config config/webpack.config.js" } }
npm run build npm run dev
需要注意的是在配置build&dev腳本的時候,我們并沒有用npx命令,實際上,在npm腳本中的命令,npm默認都是優先查找本項目下node_modules下是否存在對應的模塊及命令,如果沒找到,才會查找全局的命令多文件入口
通常一個項目中,并不是只有一個js文件,而entry默認支持多文件入口,修改output跟隨入口文件名字命名即可,簡單做如下修改:
module.exports = { entry: { index: path.resolve(base, "src", "index.js"), main: path.resolve(base, "src", "main.js") }, output: { filename: "js/[name].js", path: path.resolve(base, "dist") } }
同時創建一個簡單的main.js進行測試,再次編譯會發現在dist/js目錄下存在編譯后的index.js和main.js文件
一切皆為Modulewebpack令人興奮的一個特性就是模塊化,易于擴展其功能。webpack支持大量的模塊導入方法,比如ES6(import)、CommonJS(require)、AMD等規范,并且加入了一些自由方法,具體的可以看官方說明文檔。
用通俗的語言描述就是,webpack通過某個入口,去匹配各種模塊導入規范,發現一個模塊就根據對應配置尋找對應的loader去處理,如此往復,直到處理完畢所有依賴。
使用起來就是在modules字段中的rules(老版本名字為loaders,為保證兼容性,還是支持這個字段的)中配置test,去匹配文件(js、css、圖片資源等等),然后把這個文件交給合適的loader處理即可,所以但凡新出的框架,如果用到了獨特的語法功能,都會配套提供對應的loader工具
使用ES6等新特性目前雖然瀏覽器對ES6新特性的支持度都非常高,但仍是有部分場景下,我們只能運行ES5的代碼,這時候就需要利用到js轉碼屆的特斯拉Bebel及其插件了
yarn add babel-loader babel-core babel-preset-env
module: { rules: [ { test: /.js$/, exclude: /(node_modules|bower_components)/, use: { loader: "babel-loader", options: { presets: ["env"] } } } ] },
顯然test中匹配了所有的js文件,exclude字段去除了項目中依賴庫里的文件,use則是配置對應的loader。其中對于options,是作為參數傳遞給babel-loader的,babel的相關參數可以參考babel的官方網站,其中presets作為最主要的參數,告訴babel按照那種規則去解析代碼,當然env是一個組合,包含es2015、es2016等,當presets參數包含多個值時,babel的處理規則是倒序的,"es2017","es2016",babel會先去匹配es2016的規則。另外,對于babel的配置,也可以通過在根目錄建立.babelrc方式去配置:
//.babelrc { "presets": [ "env" ] }
當然除了擴展js的語法,有時候我們還需要擴展js的功能,比如在某些低版本的瀏覽器上運行"Hello World".includes("Hello"),這可以使用babel-polyfill這個組件,點擊這里可以了解其使用方法。
CSS當然,我們可以只讓webpack處理js文件,繼續在html文件中通過link標簽引入css文件。但顯然webpack希望前端攻城獅們也能像模塊化編寫js一樣,進行css的編寫。我們在src下創建css目錄,并創建main.css文件
/* src/css/main.css */ body{ background-color: deepskyblue; /* 我喜歡填空的藍色 */ }
//src/index.js import style from "./css/main.css"
這時候使用npm run build會發現編譯報錯,這是因為webpack無法處理載入main.css后的代碼
ERROR in ./src/css/main.css Module parse failed: Unexpected token (1:4) You may need an appropriate loader to handle this file type. | body{ | background-color: red; | } @ ./src/index.js 3:12-37
webpack官方提供css-loader專門處理導入的css模塊,當然css-loader也僅僅是完成了模塊的導入處理,使webpack在編譯時候不再報錯,實際上,還需要style-loader處理導入后的css數據,自動添加到html的style標簽中。如果你在測試過程中,僅僅添加css-loaderloader,你會發現body實際上并沒有變成背景藍
yarn add style-loader css-loader
//config webpack.config.js module->rules { test: /.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader", options: { modules: true, localIdentName: "[path][name]__[local]--[hash:base64:5]" } } ] }
當然css-loader還有一個重要配置選項,modules參數,它支持導入的css中的類名自動重命名,這樣即使在不同組件使用了相同的css類命名,經處理后互相之間也不會出現影響。看下效果:
比較常見的預編譯工具也就是Sass、Less、Stylus。在使用這三個預編譯工具前,需要安裝其對應的專屬處理程序,比如Sass的處理工具node-sass。為了配合與webpack使用,還要安裝對應的loader,比如sass-loader
yarn add sass-loader node-sass --dev
在webpack.config.js中添加對scss(Sass 3引入的新的語法格式,推薦新項目都用此)文件的支持,再起強調,webpack中loader執行順序是從右往左,從下往上。
// webpack.config.js module.exports = { ... module: { rules: [{ test: /.scss$/, use: [{ loader: "style-loader" }, { loader: "css-loader", options: { modules: true, localIdentName: "[path][name]__[local]--[hash:base64:5]" } }, { loader: "sass-loader" } }] }] } };
測試一下:
/* src/sass/main.scss */ body { background-color: blue; } .main { background-color: grey }
//src/index.js // import style from "./css/main.css" import style from "./sass/main.scss" let es6 = () => { console.log("run in es6") console.log(style) } es6();
其他兩種預編譯器可以參考各自官方文檔:less-loader、stylus-loader
像處理JS一樣處理CSS -- PostCSSPostCSS官網介紹是,利用js轉譯css的一個工具。對PostCSS的介紹,我比較認可這篇文章,PostCSS提供了一個解析器,把css轉換為抽象語法樹(AST),當然這個AST是能夠被js處理的,然后交給各種插件處理后,再將AST轉為css代碼,所以關鍵是這些插件能完成哪些功能。
AutoprefixerAutoprefixer 是一個流行的 PostCSS 插件,其作用是為 CSS 中的屬性添加瀏覽器特定的前綴。
cssnextcssnext 插件允許開發人員在當前的項目中使用 CSS 將來版本中可能會加入的新特性。需要注意這個插件本身包含了Autoprefixer功能,所以如果使用了這個插件,則不需要Autoprefixer插件。
當然PostCSS中其實也包含支持Sass、Less等的插件,這個看個人喜好,不過我本人倒是蠻期待嘗試下cssnext,畢竟大部分特性可能就是未來css支持的特性,提前熟悉下也算是預習。
更多插件可以讀這篇文章,不再敘述
安裝postcss-loader及其插件autoprefixer
yarn add postcss-loader autoprefixer --dev
在webpack.config.js中添加postcss支持,注意postcss處理css文件的位置
// webpack.config.js module.exports = { ... module: { rules: [{ test: /.scss$/, use: [{ loader: "style-loader" }, { loader: "css-loader", options: { modules: true, localIdentName: "[path][name]__[local]--[hash:base64:5]", minimize: false } }, { loader: "postcss-loader", options: { config: { path: path.resolve(base, "config", "postcss.config.js") } } }, { loader: "sass-loader" }] }] } };
如上面配置,postcss需要多帶帶的配置文件,創建config/postcss.config.js,添加如下配置:
//config/postcss.config.js module.exports = { plugins: { "autoprefixer": {} } }圖片資源
file-loader提供了對圖片資源的loader功能,并且利用 publicPath 選項還能很好的支持cdn,配合url-loader還能對小圖片直接進行數字序列化(DataURL),減少網絡請求,提高加載速度。
yarn add url-loader file-loader --dev
增加相關配置;url-loader的默認 fallback loader就是 file-loader 為了更直觀就寫了出來,傳遞給 file-loader 的參數也只需要寫在options中即可。這樣
background-image: url("../image/logo.jpg") 當我們在css文件中使用這種方式引入圖片時,就會觸發url-loader去處理
//config/webpack.config.js module.exports = { ... module: { rules: [ { test: /.(png|jpg|gif)$/, use: [ { loader: "url-loader", options: { limit: 8192, fallback: "file-loader", name: "[hash:5].[ext]", // publicPath: "https://cdn.j2do.com/", outputPath: "images/" } } ] } ] } }雖不是萬能,但卻異常強大的插件(Plugins)系統
Loader是專注于處理Webpack導入的資源模塊,而插件是對Webpack功能的擴展。除了Webpack內置的插件,開發社區提供了大量優秀的插件。當然插件也是解決問題的,我們還是以問題為導向,去介紹幾款插件。
利用 extract-text-webpack-plugin 分離css到獨立文件yarn add extract-text-webpack-plugin --dev
其中ExtractTextPlugin中fallback是指定了如果不需要提取到獨立css文件中的樣式文件,則交給 style-loade 處理,其他loader配置,跟之前沒有差異。同樣如果是預編譯文件(Sass、Less等)的話,也只需要增加對應的loader即可
module.exports = { ... module: { rules: [ { test: /.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [ { loader: "css-loader", options: { modules: true, localIdentName: "[path][name]__[local]--[hash:base64:5]" } }, { loader: "postcss-loader", options: { config: { path: path.resolve(base, "config", "postcss.config.js") } } } ] }) } ] } ... plugins: [ new ExtractTextPlugin("css/[name].css") ] };
再次運行 yarn run build 會發現生成了獨立的css文件
利用 html-webpack-plugin 自動生成 index.html 等入口文件隨著多入口以及css的分離,手動去寫html的入口文件也是一件麻煩事,這時候 html-webpack-plugin 就排上用途了, html-webpack-plugin 能夠根據某個模板文件自動生成入口的html,包括多個入口,安裝及配置如下:
yarn add html-webpack-plugin --dev
module.exports = { ... plugins: [ new ExtractTextPlugin("[name].css"), new HtmlWebpackPlugin({ title: "Index Page", template: path.resolve(base, "src", "template/index.html.tmpl"), filename: "index.html", chunks: ["index"] }), new HtmlWebpackPlugin({ title: "Main Page", template: path.resolve(base, "src", "template/index.html.tmpl"), filename: "main.html", chunks: ["main"] }), ] };
創建模板文件,注意之所以命名為 .tmpl 是為了防止 .html 可能會被loader解析,<%= ... %> 將不會被插件識別,完成變量替換。如下圖,我們的 title 是以變量形式在 webpack.config.js 中配置。該插件還支持多種模板文件,具體可見官方文檔
代碼優化壓縮<%= htmlWebpackPlugin.options.title %>
前面已經將js、css等分離到多帶帶文件,接下來就是優化壓縮這些代碼。
對于css而言,只需要配置 css-loader 的 minimize 參數為 true 即可;當然還可以利用postcss的 cssnano 插件進行代碼的壓縮和優化,據說 cssnano 是目前css壓縮優化中效果最好的工具。
對于js的壓縮,我們借助于 uglifyjs-webpack-plugin 插件
yarn add uglifyjs-webpack-plugin --dev
module.exports = { ... plugins: [ new ExtractTextPlugin("css/[name].css"), new HtmlWebpackPlugin({ title: "Index Page", template: path.resolve(base, "src", "template/index.html.tmpl"), filename: "index.html", chunks: ["index"] }), new UglifyJsPlugin() ] };借助Eslint自動代碼規范檢測及格式化
Eslint不再介紹,在webpack下使用Eslint需要如下依賴包:
yarn add eslint eslint-loader babel-eslint eslint-config-standard --dev
其中eslint是必須的,eslint-loader 是連接eslint與webpack的loader,babel-eslint 是一個eslint解析器,使其能支持es6等語法檢測,eslint-config-standard是Airbnb的規范配置,目前最流行的js規范。
安裝過程中如果有提示eslint-config-standard@11.0.0-beta.0" has unmet peer dependency "eslint-plugin-import@>=2.2.0"等等,直接安裝對應的包即可,比如:yarn add eslint-plugin-import --dev即可
eslint是規范js語法,所以他需要處理的是js文件,而且應該是先于所有loader去處理js文件,如果出錯或者不規范則糾正之,這里可以利用webpack的 enforce 屬性,設置eslint檢查,先于其他loader
module.exports = { ... module: { rules: [ { enforce: "pre", test: /.js$/, exclude: /node_modules/,//注意不要檢測node_modules里面的代碼 loader: "eslint-loader", options: { fix: true //自動修復不規范的代碼,并不是所有代碼都能自動修復的,一些縮進,引號等能直接處理 } } ... ] } }
同時還要為eslint增加對應的配置文件 .eslintrc
{ "parser": "babel-eslint", "extends": "standard", "rules": {} }
這時候再嘗試build吧,會發現一些不規范的代碼被自動修復,當然有些不規范的代碼,無法自動修復的,會直接導致錯誤;比如,聲明了一個函數,卻沒有使用!
未完待續~~(近幾天更新)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90495.html
摘要:相信很多人在格式化字符串的時候都用的語法,提出一種更先進的格式化方法并成為的標準用來替換舊的格式化語法,從開始已經實現了這一方法其它解釋器未考證。 showImg(https://segmentfault.com/img/remote/1460000018650325); 相信很多人在格式化字符串的時候都用%s % v的語法,PEP 3101 提出一種更先進的格式化方法 str.for...
摘要:前言上一次我們對的應用進行了一次全面的分析,這一次我們來聊聊。 showImg(https://segmentfault.com/img/remote/1460000020077803?w=1280&h=853); 前言 上一次我們對Paging的應用進行了一次全面的分析,這一次我們來聊聊WorkManager。 如果你對Paging還未了解,推薦閱讀這篇文章: Paging在Recy...
摘要:豐富的特性還支持通知過期等等特性。到這個就說明測試通過了。主要針對方法配置,能夠根據方法的請求參數對其進行緩存,常用于查詢操作主要針對方法配置,能夠根據方法的請求參數對其進行緩存,常用于修改操作清空緩存,主要用于刪除操作。 [TOC] Redis簡介 Redis 是一個開源的使用 ANSI C 語言編寫、遵守 BSD 協議、支持網絡、可基于內存亦可持久化的日志型、Key-Value 數...
摘要:采用完全獨立于任何程序語言的文本格式,使成為理想的數據交換語言為什么需要提到,我們就應該和來進行對比。也是一種存儲和交換文本信息的手段。那么好在哪里呢比更小更快,更易解析。使用的時候,也支持將轉成但是,我們不一定使用框架來做開發呀。 什么是JSON JSON:JavaScript Object Notation 【JavaScript 對象表示法】 JSON 是存儲和交換文本信息的語法...
摘要:目錄前言架構安裝第一個爬蟲爬取有道翻譯創建項目創建創建解析運行爬蟲爬取單詞釋義下載單詞語音文件前言學習有一段時間了,當時想要獲取一下百度漢字的解析,又不想一個個漢字去搜,復制粘貼太費勁,考慮到爬蟲的便利性,這篇文章是介紹一個爬蟲框架, 目錄 前言 架構 安裝 第一個爬蟲:爬取有道翻譯 創建項目 創建Item 創建Spider 解析 運行爬蟲-爬取單詞釋義 下載單詞語音文件 ...
閱讀 540·2021-08-31 09:45
閱讀 1646·2021-08-11 11:19
閱讀 883·2019-08-30 15:55
閱讀 821·2019-08-30 10:52
閱讀 2845·2019-08-29 13:11
閱讀 2924·2019-08-23 17:08
閱讀 2832·2019-08-23 15:11
閱讀 3066·2019-08-23 14:33