說明
- 源代碼
- 本篇主要對發布環境的配置說明
- 前面2點是對webpack的一個復習.
- 第3點開始,逐步配置部署代碼
1. Webpack發布的策略
2.1 在實際開發中,一般會有兩套方案:
- 開發期間的項目:包含了測試文件、測試數據、開發工具、測試工具等相關配置,有利于項目的開發和測試,但是這些文件僅用于開發,發布項目的時候需要刪除
- 部署期間的項目,剔除了那些客戶用不到的測試數據、測試工具和文件,比較純凈,減少了項目發布后的體積,有利于開發和部署
2.2 生產環境的配置文件
-
為了滿足我們的發布策略,需要新建一個配置文件,命名為
webpack.publish.config.js,將webpack.config.js的配置拷貝過去,剔除一些開發配置項即可. -
將
devSever節點刪掉:
devServer: {hot: true,open: true,port: 4321}
- 將
plugins節點下的熱更新插件刪掉:
new webpack.HotModuleRupluComuntPlugin()
2. Webpack從0開始使用
2.1 項目初始化
注: 使用的node版本是 12.10.0
2.1.1 新建項目(文件夾)webpack-senior
2.1.2 進入webpack-senior
新建下面三個:
- 打包之后的文件夾:
dist - 項目的源代碼:
src - webpack的配置文件:
webpack.config.js
2.1.3 初始化項目
npm init -y- 使用yarn安裝 jquery:
yarn add jquery(等同于 npm i -D jquery)
2.1.4 src的初始化
- 在其中新建如下文件和內容:
src/index.js<html><body><ul><li>這是第1個li</li><li>這是第2個li</li><li>這是第3個li</li><li>這是第4個li</li></ul></body></html>src/main.js
import $ from 'jquery' $(function(){$('li:odd').css('backgroundColor','pink');$('li:even').css('backgroundColor','marron'); })();
2.1.5 配置文件的編寫
-
上面完成了簡單的頁面和js對頁面的操作,下面寫Webpack的配置文件(webpack使用配置文件對項目進行打包構建)
-
webpack.config.jsconst path = require('path');module.exports = {entry: path.join(__dirname, './src/main.js'),output: {path: path.join(__dirname, './dist'),filename: 'bundle.js'}}
- 以上代碼指明了webpack的入口和打包文件,下面需要裝2個插件來使index.html和main.js在內存中生成:
yarn add webpack --dev(webpack是在開發環境中進行的,因此需要在npm中使用-S,在yarn中則變為 --dev)yarn add webpack-dev-server html-webpack-plugin --dev: 安裝在內存中生成index.html和main.js的插件,改寫webpack.config.js如下:
const path = require('path');const htmlWebpackPlugin = require('html-webpack-plugin');module.exports = {entry: path.join(__dirname, './src/main.js'),output: {path: path.join(__dirname, './dist'),filename: 'bundle.js'},plugin: [new htmlWebpackPlugin({template: path.join(__dirname, './src/index.html'),filename: 'index.html'})]}
- 上面已經將html頁面放到了內存中,接下來配置啟動命令:
package.json
{"scripts": {"dev": "webpack-dev-server --open --port 3000 hot"}}
2.1.6 小檢測點
對上面過程進行說明:
- 從啟動命令
npm run dev說起 - 當在命令行,輸入
npm run dev時 - 工具:
webpack-cli(安裝在開發環境, yarn add webpack-cli --dev),會以命令行啟動的目錄作為當前目錄,去尋找package.json文件 - 找到
package.json文件后,會尋找"scripts" - 找到
scripts對象后,進而找到"dev" - 然后運行命令
webpack-dev-server --open --port 3000 --hot webpack-dev-server:- 每次寫完代碼手動調用webpack去打包代碼太麻煩,因此使用 webpack-dev-server來進行自動打包構建
- 會根據
package.json中output的配置,生產一個內存中的main.js文件.
2.2 webpack中loader的配置
webpack默認只能解析.js和.json文件,若想解析其他類型的文件,需要配置loader
配置loader解析.scss
- 在src目錄下新建目錄結構
/src/css/index.scss - 在
index.scss中寫入如下:
html,
body {margin: 0;padding: 0;ul {list-style: none;padding: 0;margin: 0;}li{font-size:12px;line-height: 30px;padding-left: 10px;}.box {width: 500px;height: 230px;background: url('../images/開心.gif');background-size: cover;}
}
- 在
/src/index.html中添加如下:
<div class="box"></div>
- 在main.js中導入
index.scss:
import './css/index.scss';
此時項目肯定啟動不了,因為未配置loader的webpack不能解析.scss,下配置:
- 解析CSS、SCSS、URL加載
- 安裝依賴:
yarn add style-loader css-loader sass-loader node-sass url-loader file-loader --dev
// webpack.config.jsmodule.exports = {module:{rules:[{ test: /\.css$/, use: ['style-loader', 'css-loader'] },{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },{ test: /\.(png|gif|bump|jpg)$/, use: ['url-loader?limit=5000']}]}}
- 解析ES6的高級語法
- 安裝依賴:
yarn add babel-core babel-loader babel-plugin-transform-runtime babel-preset-env babel-preset-stage-0 --dev
// webpack.config.jsmodule.exports ={module:{rules:[{ test:/\.js$/, use:'babel-loader', exclude: /node_modules/ }]}}````````js// .babelrc{"presets": ["env", "stage-0"],"plugins": ["transform-runtime"]}
Error: Cannot find module '@babel/core': 查看報錯,是因為babel-loader的版本過高,根據提示輸入yarn add babel-loader@7 --dev即可Module not found: Error: Can't resolve 'scss-loader' in 'D:\L-rn\HeiMa\webpack-senior':沒有找到scss-loader模塊,打開package.json可以看到,里面有一個’sass-loader’,將webpack.config.js中的scss改為sass即可.
3. 使用Webpack打包項目
現在假設項目已經開發完畢,并且打算使用webpack將項目進行打包.
3.1 直接在命令行輸入webpack命令進行打包
- 直接打包,生成的項目體積會很大,許多不需要的內容都會被打包在里面
3.2 優化打包
3.2.1 新建一個打包時的webpack配置文件:
webpack.pub.config.js
3.2. 2 新建一個打包指令:
package.json
{"scripts": {"build": "webpack --config webpack.pub.config.js"}}
3.3.3 統一管理打包后的圖片
- 將打包后的所有圖片放到
dist/images中統一管理 - 改變
webpack.pub.config.js
module.exports ={module: {rules:[{ test:/\.(png|gif|bump|jpg)$/, use: ['url-loader?limit=5000&name=images/[hash:8]-[name].[ext]']}]}}
3.3.4 清除之前的打包文件
- 每次打包都刪除之前的dist文件
- 安裝插件
yarn add clean-webpack-plugin --dev - 配置:
webpack.pub.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {plugins: [new CleanWebpackPlugin()]}
- TypeError: cleanWebpackPlugin is not a constructor : 規則配置的時候出錯,不需要傳入參數下面是官網原話,拿出組件時,用到了結構賦值.
By default, this plugin will remove all files inside webpack`s output.path directory,as well as all unused webpack assets after every successful rebuild
3.3.5 將自己的代碼和第三方包分離
webpack.pub.config.js
const webpack = require('webpack');const WebpackPlugin = new webpack.optimize.CommonsChunkPlugin({name:'common',filename: 'common.js'});module.exports = {entry: {app: path.join(__dirname, './src/main.js'),common: ['jquery']},plugins:[WebpackPlugin]}
- 自動優先加載第三方模塊,在加載自己的代碼.
?
3.3.6 將所有js文件放到js文件夾下面
- webpack.pub.config.js
const WebpackPlugin = new webpack.optimize.CommonsChunkPlugin({name: 'common',- filename: 'common.js'+ filename: 'js/common.js'});module.exports = {output: {- filename:'[name].js'+ filename:'js/[name].js'}}
3.3.7 壓縮js代碼
// 壓縮JS代碼const UglifyJsPlugin = new webpack.optimize.UgliJsPlugin({compress:{warnings: false}});// 定義生產環境,進一步壓縮代碼const DefinePlugin = new webpack.DefinePlugin({'process.env.NODE_ENV': 'production'});module.exports = {plugins:[UglifyJsPlugin,DefinePlugin]}
3.3.8 壓縮HTML代碼
- webpack.config.js
const HtmlPlugin = new HtmlWebpackPlugin({template: path.join(__dirname, './src/index.html'),filename: 'index.html',minify:{// 合并多余的空格collapseWhitespace: true,// 移除注釋removeComments: true,// 移出屬性上的雙引號removeAttributeQuotes: true}});
- 更多minify參數: 官方github
?
3.3.9 將css代碼從js中抽離出來放在同一個文件夾下
- 官網
yarn add extract-text-webpack-plugin --dev
const ExtractTextPlugin = require('extract-text-webpack-plugin');module.exports = {module: {rules:[{test: /\.scss$/,use: ExtractTextPlugin.extract({fallback: 'style-loader',use: ['css-loader', 'sass-loader']})}]},plugins: [new ExtractTextPlugin("style.css")]}
- 報錯
Module build failed: CssSyntaxError: 注釋掉css的配置文件如下
module.exports = {module: {rules[// {// test: /\.css$/,// use: ExtractTextPlugin.extract({// fallback: "style-loader",// use: "css-loader"// })// }...]}}
3.3.10 抽離css時候,圖片路徑問題
- 我們希望將CSS從js代碼中抽出,單獨存放在一個css文件夾下面.
- 如果css中使用到了url屬性(如
{background: url(path)}),在抽離出來后路徑會發生變化. - 需要在抽離后,自動添加路徑如下:
````git
{test: /\.scss$/,use: ExtractTextPlugin.extract({fallback: 'style-loader',use: ['css-loader', 'sass-loader'],
+ publicPath: '../'})
}
````
3.3.11 壓縮css文件
yarn add optimize-css-assets-webpack-plugin --dev
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');plugins: [new OptimizeCssAssetsPlugin()]
TypeError: Cannot read property 'compilation' of undefined: 版本問題:yarn add optimize-css-assets-webpack-plugin@3.2.0 --dev
4.檢測點
4.1 webpack是如何提高開發效率的
- 從文件中打開
.html文件時,首先從磁盤上加載該文件的內容到內存中,然后在進行渲染 - 磁盤和內存的交互,遠遠沒有內存中直接操作快
html-webpack-plugin: 會根據給定的模板文件,生成在內存中的主頁webpack-dev-server: 會根據配置,生成一個在內存中的主入口函數- 優點是把能在內存中操作的部分,都放到內存中操作.缺點比較占用內存.
- 在開發階段,可以很方便的使用第三方庫,在生產階段,可以使用一些插件將第三方庫和源代碼進行分離,并壓縮代碼
4.2 yarn和npm的命令行在使用的時候有什么區別.
- 首先理解
開發環境和生產環境 開發環境: 即開發過程中使用到的依賴,在npm中常常使用-D來將依賴添加到開發環境(“devDependencies”)中生產環境: 項目部署到服務器上所用到的依賴,在npm中常常使用-S來講依賴添加到生產環境(“dependencies”)中- 在yarn中,使用
yarn add默認將包放在生產環境中,即對應npm的-S - 若需要添加到開發環境中,則需要使用
yarn add [packagename] --dev
4.3 webpack中loader和plugins的區別
- 原生的webpack只能理解javascript和json文件,如果遇到如.css或.jsx這類的后綴名,是無法解析的,這個時候就需要用到loader了,而某些loader無法解析的,就用到plugins.
- loader是在開發過程用到的插件,而plugin貫徹整個開發和項目部署