欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何用webpack4.0擼單頁(yè)/多頁(yè)腳手架 (jquery, react, vue, typescript)

 更新時(shí)間:2019年06月18日 14:43:31   作者:哎呦,豬先森  
這篇文章主要介紹了如何用webpack4.0擼單頁(yè)/多頁(yè)腳手架 (jquery, react, vue, typescript),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

1.導(dǎo)語(yǔ)

首先來(lái)簡(jiǎn)單介紹一下webpack:現(xiàn)代 JavaScript 應(yīng)用程序的 靜態(tài)模塊打包工具 。當(dāng) webpack 處理應(yīng)用程序時(shí),它會(huì)在內(nèi)部構(gòu)建一個(gè)會(huì)映射項(xiàng)目所需的每個(gè)模塊 的依賴圖(dependency graph),并生成一個(gè)或多個(gè) bundle 。webpack4.0出現(xiàn)之后,我們可以不用再引入一個(gè)配置文件來(lái)打包項(xiàng)目,并且它仍然有著很高的可配置性,可以很好滿足我們的需求。 在開始正文之前,首先先來(lái)看看我們要實(shí)現(xiàn)的成果:

  • 支持ES6+JQuery+Less/Scss的單頁(yè)/多頁(yè)腳手架
  • 支持ES6+React+Less/Scss+Typescript的單頁(yè)/多頁(yè)腳手架
  • 支持ES6+Vue+Less/Scss+Typescript的單頁(yè)/多頁(yè)腳手架

github地址:

基于webpack4.0搭建的腳手架(支持react/vue/typescript/es6+/jquery+less/scss)

在腳手架的開發(fā)過(guò)程中我會(huì)詳細(xì)介紹每個(gè)插件或者loader的用途以及webpack的核心理念,如有不懂或者有其他更好的想法歡迎交流。 下面是基于該文章的webpack4.0的思維導(dǎo)圖:

2.webpack核心概念

  • 入口:指示 webpack 應(yīng)該使用哪個(gè)模塊作為入口起點(diǎn)
  • 輸出:告訴 webpack 在哪里輸出它所創(chuàng)建的 bundle,以及如何命名這些文件
  • loader:讓 webpack 能夠去處理其他類型的文件,并將它們轉(zhuǎn)換為有效模塊,以供應(yīng)用程序使用
  • 插件:用于執(zhí)行范圍更廣的任務(wù)。包括:打包優(yōu)化,資源管理,注入環(huán)境變量
  • 模式:通過(guò)選擇 development, production 或 none 之中的一個(gè),來(lái)設(shè)置 mode 參數(shù),從而進(jìn)行不同的打包優(yōu)化
  • 瀏覽器兼容性:支持所有符合ES5 標(biāo)準(zhǔn)的瀏覽器(不支持 IE8 及以下版本)下面提供官網(wǎng)的打包模型

3.支持ES6+JQuery+Less/Scss的單頁(yè)/多頁(yè)腳手架

在實(shí)現(xiàn)腳手架之前,假設(shè)我們已經(jīng)創(chuàng)建了目錄和package.json文件,接下來(lái)先安裝webpack相關(guān)依賴:

// 此處建議安裝局部依賴,安裝全局依賴可能會(huì)出現(xiàn)版本問(wèn)題
npm install -D webpack webpack-cli

因?yàn)轫?xiàng)目要支持es6+,我們還需要安裝babel相關(guān)依賴:

npm install -D babel-loader @babel/core @babel/preset-env 

這個(gè)時(shí)候可以開始配置我們的腳手架邏輯了,為了項(xiàng)目結(jié)構(gòu)清晰易于維護(hù),我們建一個(gè)build目錄專門放webpack構(gòu)建的腳本,webpack默認(rèn)的配置文件是webpack.config.js,由于實(shí)際項(xiàng)目需要,我們將其拆分為3個(gè)文件,分別是webpack通用配置文件webpack.base.js,開發(fā)環(huán)境配置文件webpack.dev.js以及生產(chǎn)環(huán)境配置文件webpack.prod.js。

我們先處理webpack.common.js文件

const path = require('path');
const webpack = require('webpack');

module.exports = {
 entry: {
  main: './src/index.js',
 },
 output: {
  path: path.resolve(__dirname, '../dist'),
 },
 module: {
  rules: [
   // 將es6編譯成es5
   { 
    test: /\.jsx?$/, // ?表示x有0個(gè)或一個(gè)
    exclude: /node_modules/, // 不編譯某個(gè)目錄下的文件
    include: path.resolve(__dirname, '../src'), // 只在include包含的目錄下進(jìn)行l(wèi)oader編譯
    use: [
     "babel-loader",
    ]
   },
  ]
 }
}

為了項(xiàng)目后期的開發(fā)和維護(hù),我們建立好項(xiàng)目結(jié)構(gòu):

public目錄是事先準(zhǔn)備好的html模版,這里就不介紹了,其他目錄可根據(jù)具體項(xiàng)目進(jìn)行設(shè)置。

我們還需要一個(gè)插件將打包后的文件植入到html模版中并導(dǎo)出到dist目錄下,這里使用html-webpack-plugin來(lái)實(shí)現(xiàn)

npm install -D html-webpack-plugin

現(xiàn)在webpack.base.js為如下:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const template = path.resolve(__dirname, '../public/index.html');

module.exports = {
 entry: {
  main: './src/index.js'
 },
 output: {
  path: path.resolve(__dirname, '../dist')
 },
 module: {
  rules: [
   // 將es6編譯成es5
   { 
    test: /\.jsx?$/, // ?表示x有0個(gè)或一個(gè)
    exclude: /node_modules/, // 不編譯某個(gè)目錄下的文件
    include: path.resolve(__dirname, '../src'), // 只在include包含的目錄下進(jìn)行l(wèi)oader編譯
    use: [
     "babel-loader",
    ]
   },
  ]
 },
 plugins: [
  new HtmlWebpackPlugin({
   template,
   filename: 'index.html'
  })
 ]
}

為了打包項(xiàng)目,我們需要在webpack.prod.js目錄下進(jìn)行配置,此處需要一個(gè)模塊webpack-merge將wepack基礎(chǔ)配置合并進(jìn)生產(chǎn)配置,我們先來(lái)安裝一下:

npm install -D webpack-merge

webpack.prod.js配置如下:

const merge = require('webpack-merge');
const base = require('./webpack.base');

module.exports = merge({
 mode: 'production',
 output: {
  filename: 'js/[name]_[contenthash].js', // 入口和內(nèi)容hash組成的文件名,也可以是hash
		chunkFilename: 'js/[name]_[contenthash].chunk.js'
 }
}, base)

然后在package.json里添加執(zhí)行腳本:

"scripts": {
 "build": "webpack --config ./build/webpack.prod.js"
 }

webpack默認(rèn)會(huì)找名為webpack.config.js的文件,由于我們將其拆解為prod和dev,所以我們要手動(dòng)指定webpack執(zhí)行的文件,添加--config,即可手動(dòng)指定目錄。下面我們開始寫一段代碼試試吧,在index.js中寫入如下es6代碼:

// index.js
let name = 'xuxi';
let say = (name) => {
 alert(name)
};
say(name);

下面我們執(zhí)行:

npm run build

此時(shí)我們會(huì)看見(jiàn)項(xiàng)目中多了一個(gè)dist目錄,里面的html也植入了相應(yīng)的代碼,

在瀏覽器中打開:

ok,第一步完成。 下一步是支持css,我們先安裝如下幾個(gè)模塊:

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

在webpack.base.js中的module中添加如下代碼:

module: {
  rules: [
   // 將es6編譯成es5
   { 
    test: /\.jsx?$/, // ?表示x有0個(gè)或一個(gè)
    exclude: /node_modules/, // 不編譯某個(gè)目錄下的文件
    include: path.resolve(__dirname, '../src'), // 只在include包含的目錄下進(jìn)行l(wèi)oader編譯
    use: [
     "babel-loader",
    ]
   },
   // 加載css
   {
    test: /\.css$/,
    use: ['style-loader', 'css-loader'],
   },
  ]
 }

注意,laoder的加載順序是從下往上,從右往左的,所以配置loader的時(shí)候要注意一下順序。 此時(shí)在styles目錄下加入app.css,在js中引入:

// app.css
#root {
 background-color: #f0c;
 height: 100px;
}

// index.js
import './styles/app.css'

此時(shí)打開瀏覽器,可以看到css生效了:

現(xiàn)在css導(dǎo)入雖然生效了,但是是有js動(dòng)態(tài)創(chuàng)建添加到head里面的,如果后期項(xiàng)目復(fù)雜了,將會(huì)嚴(yán)重影響項(xiàng)目的加載速度,所以我們這里需要另一個(gè)插件,對(duì)css進(jìn)行代碼分割,單獨(dú)生成css文件:

npm isntall mini-css-extract-plugin -D

根據(jù)該插件的官方配置,我們需要把style-loader替換成該插件提供的loader,并配置導(dǎo)出的css文件目錄和文件名,為了提高開發(fā)環(huán)境構(gòu)建速度,我們只在生產(chǎn)環(huán)境分割css:

// webpack.prod.js
const merge = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const base = require('./webpack.base');

module.exports = merge({
 mode: 'production',
 output: {
  filename: 'js/[name]_[contenthash].js', // 入口和內(nèi)容hash組成的文件名,也可以是hash
		chunkFilename: 'js/[name]_[contenthash].chunk.js'
 },
 module: {
  rules: [
   {
    test: /\.css$/,
    use: [ // loader解析的順序是從下到上,從右到左的順序
     {
      loader: MiniCssExtractPlugin.loader,
      options: {
       filename: '[name].css',
       chunkFilename: '[name].css',
       publicPath: '../' //****最后打包的時(shí)候替換引入文件路徑
      },
     },
     // 'style-loader', 使用MiniCssExtractPlugin時(shí)就不能使用style-loader了
     {
      loader: 'css-loader',
      options: {
       importLoaders: 2 //該方式可以讓@import引入的css文件再次執(zhí)行一邊css打包loader
      }
     },
    ]
   }
  ]
 },
 plugins: [
  new MiniCssExtractPlugin({
   // Options similar to the same options in webpackOptions.output
   // both options are optional
   filename: 'css/[name]_[hash].css',
   chunkFilename: 'css/[name]_[hash].chunk.css',
   }),
 ]
}, base)

由于我們?cè)赿ev和prod環(huán)境的css-loader不一樣,所以我們將base的css-loader配置刪除,移到dev下

// webpack.dev.js
const base = require('./webpack.base');
const merge = require('webpack-merge');
const webpack = require('webpack');

module.exports = merge({
 mode: 'development',
 module: {
  rules: [
   {
    test: /\.css$/,
    use: [ // loader解析的順序是從下到上,從右到左的順序
     'style-loader', //使用MiniCssExtractPlugin時(shí)就不能使用style-loader了
     {
      loader: 'css-loader',
      options: {
       importLoaders: 2 //該方式可以讓@import引入的css文件再次執(zhí)行一邊css打包loader
      }
     },
    ]
   }
  ]
 },
 output: {
		filename: '[name].js',
		chunkFilename: '[name].js',
	}
}, base)

ok,此時(shí)我們就完成一個(gè)基本的打包es6,css的模塊打包工具,為了支持更高的es6+語(yǔ)法,我們配置.babelrc文件,以及安裝相應(yīng)的npm包:

npm install @babel/polyfill core-js -D

.babelrc文件如下:

{
 "presets": [
  [
   "@babel/preset-env", // 將ES6語(yǔ)法轉(zhuǎn)換為es5
   {
    "useBuiltIns": "usage", // 只編譯需要編譯的代碼
    "corejs": "3.0.1",
   }
  ],
  ]
}

我們會(huì)看到babelrc文件里面有"useBuiltIns": "usage", 這個(gè)配置涉及到一個(gè)關(guān)于webpack打包的高級(jí)用法,tree-shaking。

tree-shaking:用于描述移除 JavaScript 上下文中的未引用代碼(dead-code)。它依賴于 ES2015 模塊語(yǔ)法的靜態(tài)結(jié)構(gòu)特性,例如 importexport 。這個(gè)術(shù)語(yǔ)和概念實(shí)際上是由 ES2015 模塊打包工具 rollup 普及起來(lái)的。

我們通過(guò)使用tree-shaking,可以極大的減少代碼的體積,對(duì)于提高打包性能很有幫助。為了使tree-shaking能生效,我們還要在webpack配置文件中開啟:

// webpack.base.js
optimization: {
  usedExports: true
 }

還有一個(gè)問(wèn)題,由于tree-shaking是基于import 和export的,當(dāng)我們用import引入css文件時(shí),是沒(méi)有導(dǎo)出的,所以我們需要配置忽略css文件的tree-shaking,在package.json中添加如下配置:

// package.json
"sideEffects": [
 "*.css",
 "*.less"
 ],

在打包的過(guò)程中,每次執(zhí)行打包都會(huì)新建一個(gè)打包文件,我們想要每次打包之前都清除上一次打包的文件怎么辦呢?我們可以使用clean-webpack-plugin來(lái)實(shí)現(xiàn),首先先安裝,然后具體配置如下:

// webpack.prod.js
plugins: [
  new CleanWebpackPlugin()
 ],

該插件會(huì)默認(rèn)清除dist目錄下的打包文件。 接下來(lái)我們安裝jquery:

npm install jquery -S

在index.js引入并使用:

import $ from 'jquery';
import './styles/app.css'

console.log($('#root').html('hello world'));

執(zhí)行npm run build后,我們?cè)跒g覽器中打開,即可看到j(luò)q的作用:

但是我們看dist目錄下的js文件,發(fā)現(xiàn)jquery和業(yè)務(wù)代碼都打包進(jìn)一個(gè)頁(yè)面了,這樣會(huì)導(dǎo)致當(dāng)業(yè)務(wù)復(fù)雜時(shí),整個(gè)頁(yè)面代碼會(huì)非常大,我們進(jìn)一步做優(yōu)化,即js代碼分割。 根據(jù)webpack官網(wǎng)的方案,我們只需要進(jìn)行簡(jiǎn)單的配置,便可以進(jìn)行對(duì)js代碼分割:

//webpack.base.js
optimization: {
  splitChunks: {
   chunks: 'all',
   // chunks: 'async', // async表示只對(duì)異步代碼進(jìn)行分割
   minSize: 30000, // 當(dāng)超過(guò)指定大小時(shí)做代碼分割
   // maxSize: 200000, // 當(dāng)大于最大尺寸時(shí)對(duì)代碼進(jìn)行二次分割
   minChunks: 1,
   maxAsyncRequests: 5,
   maxInitialRequests: 3,
   automaticNameDelimiter: '_',
   name: true,
   cacheGroups: { // 緩存組:如果滿足vendor的條件,就按vender打包,否則按default打包
    vendors: {
     test: /[\\/]node_modules[\\/]/,
     priority: -10, // 權(quán)重越大,打包優(yōu)先級(jí)越高
     // filename: 'js/vender.js' //將代碼打包成名為vender.js的文件
     name: 'vender'
    },
    default: {
     minChunks: 2,
     priority: -20,
     name: 'common',
     // filename: 'js/common.js',
     reuseExistingChunk: true // 是否復(fù)用已經(jīng)打包過(guò)的代碼
    }
   }
  },
  usedExports: true
 }

由于篇幅限制,splitChunks的具體配置我通過(guò)注釋寫出來(lái)了,如果想了解更詳細(xì)的配置,后面大家可以去webpack官網(wǎng)查看。此時(shí)執(zhí)行npm run build,我們可以看到代碼已經(jīng)進(jìn)行了分割:

當(dāng)然只滿足與css和js的打包還遠(yuǎn)遠(yuǎn)不夠,我們項(xiàng)目中還會(huì)用到各種圖片,字體圖標(biāo),css預(yù)編譯語(yǔ)言如less或者scss,由于這部分的安裝比較簡(jiǎn)單,我們直接上代碼。 首先安裝相關(guān)依賴:

npm install url-loader file-loader less less-loader

此時(shí)我們webpack.base.js中module變?yōu)椋?/p>

module: {
  rules: [
   // 將es6編譯成es5
   { 
    test: /\.jsx?$/, // ?表示x有0個(gè)或一個(gè)
    exclude: /node_modules/, // 不編譯某個(gè)目錄下的文件
    include: path.resolve(__dirname, '../src'), // 只在include包含的目錄下進(jìn)行l(wèi)oader編譯
    use: [
     "babel-loader",
    ]
   },
   // 加載解析文件資源
   {
    test: /\.(jpg|png|gif)$/,
    use: {
     loader: 'url-loader', // 和file-loader功能相同,但更智能
     options: {
      // 配置打包后的文件名,具體可看webpack的file-loader文檔
      name: '[name].[ext]?[hash]',
      outputPath: 'images/',
      limit: 4096 // 當(dāng)圖片大小大于4k時(shí)將以文件形式輸出,否則以base64輸出
     }
    }
   },
   // 引入字體,svg等文件
   {
    test: /\.(eot|ttf|svg)$/,
    use: {
     loader: 'file-loader'
    }
   }
  ]
 },

為了支持less,我們修改一下dev和prod文件:

// webpack.dev.js
module: {
  rules: [
   {
    test: /\.(css|less)$/,
    use: [ // loader解析的順序是從下到上,從右到左的順序
     'style-loader', //使用MiniCssExtractPlugin時(shí)就不能使用style-loader了
     {
      loader: 'css-loader',
      options: {
       importLoaders: 2 //該方式可以讓@import引入的css文件再次執(zhí)行一邊css打包loader
      }
     },
     'less-loader',
    ]
   }
  ]
 }

// webpack.prod.js
module: {
  rules: [
   {
    test: /\.(css|less)$/,
    use: [ // loader解析的順序是從下到上,從右到左的順序
     {
      loader: MiniCssExtractPlugin.loader,
      options: {
       filename: '[name].css',
       chunkFilename: '[name].css',
       publicPath: '../' //****最后打包的時(shí)候替換引入文件路徑
      },
     },
     {
      loader: 'css-loader',
      options: {
       importLoaders: 2 //該方式可以讓@import引入的css文件再次執(zhí)行一邊css打包loader
      }
     },
     'less-loader'
    ]
   }
  ]
 }

我們寫一段less代碼試試:

body {
 #root {
  background-color: #000;
  color: #fff;
 }
}

我們執(zhí)行build之后在瀏覽器打開看看效果:

ok,至此,我們第一步也是最重要的一步已經(jīng)完成了,由于開發(fā)項(xiàng)目的時(shí)候不可能每次改動(dòng)代碼都構(gòu)建一次,這樣時(shí)間成本太大了,我們想要實(shí)時(shí)看到改變的內(nèi)容,這個(gè)時(shí)候就要用webpack4.0提供的devServer了,它使得我們項(xiàng)目可以支持熱更新和熱模塊替換,我們需要在開發(fā)環(huán)境下對(duì)其進(jìn)行配置,具體如下: 首先安裝開發(fā)服務(wù)器模塊:

npm install webpack-dev-server -D

接著配置dev文件:

webpack.dev.js
const base = require('./webpack.base');
const merge = require('webpack-merge');
const webpack = require('webpack');

module.exports = merge({
 mode: 'development',
 module: {
  rules: [
   {
    test: /\.(css|less)$/,
    use: [ // loader解析的順序是從下到上,從右到左的順序
     'style-loader', //使用MiniCssExtractPlugin時(shí)就不能使用style-loader了
     'vue-style-loader',
     {
      loader: 'css-loader',
      options: {
       importLoaders: 2 //該方式可以讓@import引入的css文件再次執(zhí)行一邊css打包loader
      }
     },
     // 'sass-loader',
     'less-loader',
     'postcss-loader',
    ]
   }
  ]
 },
 // 服務(wù)器配置
 devServer: {
  port: '8081',
  // 當(dāng)使用 HTML5 History API 時(shí),任意的 404 響應(yīng)都可能需要被替代為 index.html
  historyApiFallback: true, // 解決單頁(yè)面路由問(wèn)題,
  contentBase: '../dist',
  open: true, //自動(dòng)打開瀏覽器
  hot: true, // 開啟熱替換, css代碼跟新不刷新頁(yè)面
  // hotOnly: true 開啟后只有手動(dòng)配置才能更新,即使hot為true也不刷新瀏覽器
  proxy: {
   index: '', // 將index設(shè)置為空,可以對(duì)根路徑進(jìn)行轉(zhuǎn)發(fā)
   'api/get': 'xxxx.com/api', // 第一種方式,直接代理到api路徑
   'api/vue': { // 第二種方式,在路徑需要臨時(shí)替換時(shí)使用
    target: 'xxxx.com/api',
    pathRewrite: {
     'head': 'demo' //此時(shí)訪問(wèn)head路徑將被代理到demo下
    },
    secure: false, //對(duì)https請(qǐng)求的配置,false為支持https
    changeOrigin: true //做代理分發(fā)時(shí)允許訪問(wèn)其他網(wǎng)站,突破網(wǎng)站限制,建議在開發(fā)環(huán)境使用
   },

  }
 },
 plugins: [
  new webpack.HotModuleReplacementPlugin()
 ],
 output: {
		filename: '[name].js',
		chunkFilename: '[name].js',
	}
}, base)

以上代碼中,要使用熱模塊替換,我們需要用到webpack自己集成的插件webpack.HotModuleReplacementPlugin,在devServer中,我們還可以設(shè)置開發(fā)環(huán)境中的代理proxy,這已經(jīng)是目前開發(fā)的默認(rèn)模式了,代碼中一些屬性的用法和含義我都做了注釋,如果大家有興趣,可以查看webpack原版官方文檔,那里有更詳細(xì)的配置信息。 我們?cè)賮?lái)修改package.json,添加開發(fā)環(huán)境的運(yùn)行指令:

// 在script里面添加
"start": "webpack-dev-server --config ./build/webpack.dev.js",

我們執(zhí)行 npm start,此時(shí)會(huì)自動(dòng)打開瀏覽器,運(yùn)行我們的項(xiàng)目。

到此,我們基本的一個(gè)支持ES6+Less/css+JQuery的單頁(yè)應(yīng)用打包工具已經(jīng)做好了,當(dāng)然這只是基礎(chǔ),后面的多頁(yè)應(yīng)用,vue/react/typescript都是在這個(gè)基礎(chǔ)上構(gòu)建的,讓我們拭目以待。

多頁(yè)面應(yīng)用:

我們開發(fā)多頁(yè)面應(yīng)用還是需要用到之前使用的html-webpack-plugin插件,此時(shí)我們需要定義多個(gè)入口:

// webpack.base.js
entry: {
  main: './src/index.js',
  about: './src/about.js'
 }

plugins: [
new HtmlWebpackPlugin(
  {
   template,
   title: 'webpack打包但單應(yīng)用',
   chunks: ['vender', 'main'],
   filename: 'index.html'
  }
 ),
 new HtmlWebpackPlugin(
  {
   template,
   title: '關(guān)于我們',
   chunks: ['vender', 'about'],
   filename: 'about.html'
  }
 ),
]

template是我們定義的public下的html路徑,title是我們要植入html模版中的titl標(biāo)簽中的內(nèi)容,我們?cè)趇ndex.html中這么使用:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title><%= htmlWebpackPlugin.options.title %></title>
 <link rel="shortcut icon" href="./favicon.ico" rel="external nofollow" >
</head>
<body>
 <div id="root"></div>
</body>
</html>

這樣,webpack配置的title就可以動(dòng)態(tài)的添加到html頁(yè)面中了,這里我要說(shuō)一下在new HtmlWebpackPlugin中我們添加了chunks數(shù)組,這個(gè)數(shù)組就是我們要打包進(jìn)頁(yè)面的js,main和about分別代表入口的名字,vender就是我們定義optimization時(shí)里面cacheGroups屬性值中vendors中定義的name,當(dāng)代碼超過(guò)30000b時(shí)就會(huì)生成vender.js文件。 此時(shí)我們執(zhí)行npm run build,打包結(jié)束后將會(huì)生成2個(gè)html頁(yè)面,對(duì)應(yīng)的文件依賴也會(huì)引入,在瀏覽器中打開,親測(cè)有效~

這樣,一個(gè)基本的多頁(yè)面打包工具就開發(fā)完成了,不過(guò)還有幾點(diǎn)優(yōu)化:

  • 代碼壓縮,
  • 第三方模塊懶編譯,我們可以使用webpack提供的dll技術(shù)做優(yōu)化
  • pwa技術(shù)引入 下面分別是相關(guān)實(shí)現(xiàn): 1.代碼壓縮,我們使用terser-webpack-plugin壓縮js,用optimize-css-assets-webpack-plugin壓縮css
npm install terser-webpack-plugin optimize-css-assets-webpack-plugin -D

我們?cè)趙ebpack.prod.js中添加一下配置:

// 導(dǎo)入模塊
// 壓縮css
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
// 壓縮js
const TerserPlugin = require('terser-webpack-plugin');

// 配置module.exports,添加配置如下
optimization: {
  minimizer: [
   new TerserPlugin({ // 壓縮js代碼
    cache: true, // 啟用文件緩存
    parallel: true, // 使用多進(jìn)程并行執(zhí)行任務(wù)來(lái)提高構(gòu)建效率
    sourceMap: true, // 將錯(cuò)誤消息位置映射到模塊
    terserOptions: {
     drop_console: true, // 打包時(shí)剔除所有console.log
     drop_debugger: true // 打包時(shí)剔除所有debugger
    }
   }), 
   new OptimizeCSSAssetsPlugin({})] // 壓縮css代碼
 },

pwa:漸進(jìn)式網(wǎng)絡(luò)應(yīng)用程序(progressive web application - PWA),是一種可以提供類似于native app(原生應(yīng)用程序) 體驗(yàn)的 web app(網(wǎng)絡(luò)應(yīng)用程序)。首先我們安裝依賴:

npm install workbox-webpack-plugin --save-dev

在需要做pwa的頁(yè)面里加入如下腳本啟動(dòng):

if ('serviceWorker' in navigator) { window.addEventListener('load', () => {
   navigator.serviceWorker.register('/service-worker.js').then(registration => {
    console.log('SW registered: ', registration);
   }).catch(registrationError => {
    console.log('SW registration failed: ', registrationError);
    });
   });
 }

dll文件優(yōu)化打包速度 關(guān)于dll問(wèn)題,我們可以在官網(wǎng)上查詢具體的使用方法,這里就不具體說(shuō)明了。

至此,我們關(guān)于開發(fā)基于ES6+JQuery+Less/Scss的單頁(yè)/多頁(yè)腳手架就告于段落了,下面我們來(lái)集成對(duì)react/vue/typescript的支持。

1.支持react

我們首先安裝一個(gè)babel模塊:

npm install --save-dev @babel/preset-react

然后在.babelrc中加入如下配置:

{
 "presets": [
 [
  "@babel/preset-react",
  {
  "pragma": "dom", // default pragma is React.createElement
  "pragmaFrag": "DomFrag", // default is React.Fragment
  "throwIfNamespace": false // defaults to true
  }
 ]
 ]
}

然后在index.js中寫入一段react代碼:

import React, {Component} from 'react'
import ReactDOM from 'react-dom'

class App extends Component {
 render() {
  return <div>react frame content.</div>
 }
}

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

打包后即可在瀏覽器中看到效果。

2.支持vue

首先先安裝對(duì)應(yīng)npm包:

npm install -D vue-loader vue-template-compiler

之后在webpack的配置文件中寫入如下代碼:

// webpack.base.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
 module: {
 rules: [
  // ... other rules
  {
  test: /\.vue$/,
  loader: 'vue-loader'
  }
 ]
 },
 plugins: [
 // make sure to include the plugin!
 new VueLoaderPlugin()
 ]
}

如果要想解析.vue文件中的style,我們需要使用vue-style-loader模塊,安裝之后將其添加到loder中即可。 接下來(lái)我們寫個(gè)簡(jiǎn)單的vue試一下吧:

<template>
 <div class="example">
  {{ msg }}
  <img src="~/images/logo.png" />
  <img :src="imgSrc" />
 </div>
</template>

<script>
import Logo from 'images/logo.png';
import 'css/common.css';

export default {
 data () {
 return {
  msg: 'Hello world!單獨(dú)的',
  imgSrc: Logo
 }
 }
}
</script>

<style lang="less">
.example {
 color: red;
 img {
  border: 2px solid #000;
 }
}
</style>

運(yùn)行dev在瀏覽器中即可看到效果。 值得注意的是vue文件中引入資源的問(wèn)題,使用相對(duì)路徑會(huì)有問(wèn)題,這里我們可以使用~/images/logo.png的方式或者require的方式來(lái)引入圖片。

3.支持typescript

這里我們使用awesome-typescript-loader來(lái)編譯typescript文件,也是官方推薦的一個(gè)加載器:

npm install awesome-typescript-loader --save-dev

然后我們?cè)趙ebpack的配置文件base中,在module的rules里加入如下代碼:

{
  test: /\.tsx?$/,
  loader: 'awesome-typescript-loader'
  }

最后一步,添加tsconfig.json文件:

{
 "compilerOptions": {
  "noImplicitAny": true,
  "removeComments": true
 },
 "awesomeTypescriptLoaderOptions": {
  /* ... */
 }
}

該文件有很多靈活的配置項(xiàng),大家如果想了解更多可以去typescript官網(wǎng)上查看相關(guān)文檔。 至此,所有的配置都完成了,是不是很累?哈哈,當(dāng)然腳手架中還存在一些優(yōu)化的地方,歡迎大家可以一起完善。

未完成的優(yōu)化點(diǎn):

  • vue文件內(nèi)部style無(wú)法獨(dú)立抽出樣式,只能通過(guò)引入css文件的方式加載樣式
  • 公用css文件問(wèn)題:多頁(yè)面打包時(shí),如果都引入了同一個(gè)css,無(wú)法服用這個(gè)css,希望能將這個(gè)css文件作為一個(gè)公共模塊單獨(dú)引用

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • React使用useEffect解決setState副作用詳解

    React使用useEffect解決setState副作用詳解

    這篇文章主要為大家介紹了React使用useEffect解決setState副作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • React報(bào)錯(cuò)Too many re-renders解決

    React報(bào)錯(cuò)Too many re-renders解決

    這篇文章主要為大家介紹了React報(bào)錯(cuò)Too many re-renders解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • react-intl實(shí)現(xiàn)React國(guó)際化多語(yǔ)言的方法

    react-intl實(shí)現(xiàn)React國(guó)際化多語(yǔ)言的方法

    這篇文章主要介紹了react-intl實(shí)現(xiàn)React國(guó)際化多語(yǔ)言的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 關(guān)于react hook useState連續(xù)更新對(duì)象的問(wèn)題

    關(guān)于react hook useState連續(xù)更新對(duì)象的問(wèn)題

    這篇文章主要介紹了關(guān)于react hook useState連續(xù)更新對(duì)象的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 歸納總結(jié)Remix?表單常用方法及示例詳解

    歸納總結(jié)Remix?表單常用方法及示例詳解

    這篇文章主要為大家歸納總結(jié)了Remix?表單常用方法及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • JavaScript中React 面向組件編程(下)

    JavaScript中React 面向組件編程(下)

    在React面向組件編程中,除了上一章節(jié)的組件實(shí)例的三大核心屬性以外,還有很多重要的內(nèi)容比如:React 的生命周期,受控組件與非受控組件,高階函數(shù)和函數(shù)柯里化的理解等,在本文中會(huì)給大家繼續(xù)講解React 面向組件編程中剩余的內(nèi)容
    2023-03-03
  • react-native-tab-navigator組件的基本使用示例代碼

    react-native-tab-navigator組件的基本使用示例代碼

    本篇文章主要介紹了react-native-tab-navigator組件的基本使用示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-09-09
  • React組件通信實(shí)現(xiàn)流程詳解

    React組件通信實(shí)現(xiàn)流程詳解

    這篇文章主要介紹了React組件通信,在開發(fā)中組件通信是React中的一個(gè)重要的知識(shí)點(diǎn),本文通過(guò)實(shí)例代碼給大家講解react中常用的父子、跨組件通信的方法,需要的朋友可以參考下
    2022-12-12
  • 淺談react路由傳參的幾種方式

    淺談react路由傳參的幾種方式

    這篇文章主要介紹了淺談react路由傳參的幾種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • React使用TypeScript的最佳實(shí)踐和技巧

    React使用TypeScript的最佳實(shí)踐和技巧

    在React項(xiàng)目中使用TypeScript可以顯著提高代碼的可維護(hù)性和可讀性,并提供強(qiáng)大的類型檢查功能,減少運(yùn)行時(shí)錯(cuò)誤,以下是一些優(yōu)雅地將TypeScript集成到React項(xiàng)目中的最佳實(shí)踐和技巧,需要的朋友可以參考下
    2024-06-06

最新評(píng)論