å¨å端ï¼è¯´å°manifest
ï¼å
¶å®æ¯ææ§ä¹çï¼å°±æäºè§£çæ
åµæ¥è¯´ï¼manifest
å¯ä»¥æ代ä¸åå«ä¹ï¼
-
html
æ ç¾çmanifest
å±æ§: 离线ç¼åï¼ç®å已被åºå¼ï¼ - PWA: å°Webåºç¨ç¨åºå®è£ å°è®¾å¤ç主å±å¹
- wbbpackä¸webpack-manifest-pluginæ件æå
åºæ¥ç
manifest.json
æ件ï¼ç¨æ¥çæä¸ä»½èµæºæ¸ åï¼ä¸ºå端渲ææå¡ - webpackä¸DLLæå
æ¶,è¾åºç
manifest.json
æ件ï¼ç¨æ¥åæå·²ç»æå è¿çæ件ï¼ä¼åæå é度å大å°
ä¸é¢æ们æ¥ä¸ä¸ä»ç»ä¸
htmlå±æ§
<!DOCTYPE html>
<html lang="en" manifest="/tc.mymanifest">
<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>Document</title>
<link rel="stylesheet" href="/theme.css">
<script src="/main.js"></script>
<script src="/main2.js"></script>
</head>
<body>
</body>
</html>
å¤å¶ä»£ç
æµè§å¨è§£æè¿æ®µhtmlæ ç¾æ¶ï¼å°±ä¼å»è®¿é®tc.mymanifest
è¿ä¸ªæ件ï¼è¿æ¯ä¸ä¸ªç¼åæ¸
åæ件
tc.mymanifest
# v1 è¿æ¯æ³¨é
CACHE MANIFEST
/theme.css
/main.js
NETWORK:
*
FALLBACK:
/html5/ /404.html
å¤å¶ä»£ç
CACHE MANIFEST
æå®éè¦ç¼åçæ件ï¼ç¬¬ä¸æ¬¡ä¸è½½å®æ以åï¼æ件é½ä¸ä¼åä»ç½ç»è¯·æ±äºï¼å³ä½¿ç¨æ·ä¸æ¯ç¦»çº¿ç¶æï¼é¤étc.mymanifest
æ´æ°äºï¼ç¼åæ¸
åæ´æ°ä¹åï¼æä¼å次ä¸è½½ãæ è®°äºmanifestçhtmlæ¬èº«ä¹è¢«ç¼å
NETWORK
æå®éç¼åæ件ï¼ææ类似èµæºç请æ±é½ä¼ç»è¿ç¼åï¼å³ä½¿ç¨æ·å¤äºç¦»çº¿ç¶æï¼ä¹ä¸ä¼è¯»ç¼å
FALLBACK
æå®äºä¸ä¸ªåå¤é¡µé¢ï¼å½èµæºæ æ³è®¿é®æ¶ï¼æµè§å¨ä¼ä½¿ç¨è¯¥é¡µé¢ã
æ¯å¦ç¦»çº¿è®¿é®/html5/ç®å½æ¶ï¼å°±ä¼ç¨æ¬å°ç/404.html页é¢
ç¼åæ¸
åå¯ä»¥æ¯ä»»æåç¼åï¼ä¸è¿å¿
é¡»æå®content-type
å±æ§ä¸ºtext/cache-manifest
é£å¦ä½æ´æ°ç¼åï¼ä¸è¬æ以ä¸å ç§æ¹å¼ï¼
- ç¨æ·æ¸ 空æµè§å¨ç¼å
- manifest æ件被修æ¹(å³ä½¿æ³¨é被修æ¹)
- ç±ç¨åºæ¥æ´æ°åºç¨ç¼å
éè¦ç¹å«æ³¨æï¼ç¨æ·ç¬¬ä¸æ¬¡è®¿é®è¯¥ç½é¡µï¼ç¼åæ件ä¹åï¼ç¬¬äºæ¬¡è¿å
¥è¯¥é¡µé¢ï¼åç°tc.mymanifest
ç¼åæ¸
åæ´æ°äºï¼äºæ¯ä¼éæ°ä¸è½½ç¼åæ件ï¼ä½æ¯ï¼ç¬¬äºæ¬¡è¿å
¥æ¾ç¤ºç页é¢ä»ç¶æ§è¡çæ¯æ§æ件ï¼ä¸è½½çæ°æ件ï¼åªä¼å¨ç¬¬ä¸æ¬¡è¿å
¥è¯¥é¡µé¢åæ§è¡ï¼ï¼ï¼
å¦æå¸æç¨æ·ç«å³çå°æ°å 容ï¼éè¦jsçå¬æ´æ°äºä»¶ï¼éæ°å 载页é¢
window.addEventListener('load', function (e) {
window.applicationCache.addEventListener('updateready', function (e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// æ´æ°ç¼å
// éæ°å è½½
window.applicationCache.swapCache();
window.location.reload();
} else {
}
}, false);
}, false);
å¤å¶ä»£ç
建议对tc.mymanifest
ç¼åæ¸
å设置永ä¸ç¼å
ä¸è¿ï¼manifestä¹æå¾å¤ç¼ºç¹ï¼æ¯å¦éè¦æå¨ä¸ä¸ªä¸ªå¡«åç¼åçæ件ï¼æ´æ°æ件ä¹åéè¦äºæ¬¡å·æ°ï¼å¦ææ´æ°çèµæºä¸æä¸ä¸ªèµæºæ´æ°å¤±è´¥äºï¼å°å¯¼è´å ¨é¨æ´æ°å¤±è´¥ï¼å°ç¨åä¸ä¸çæ¬çç¼å
HTML5è§èä¹åºå¼äºè¿ä¸ªå±æ§ï¼å æ¤ä¸å»ºè®®ä½¿ç¨
PWA
为äºå®ç°PWAåºç¨æ·»å è³æ¡é¢çåè½ï¼é¤äºè¦æ±ç«ç¹æ¯æHTTPSä¹å¤ï¼è¿éè¦åå¤ manifest.json
æ件å»é
ç½®åºç¨çå¾æ ãå称çä¿¡æ¯
<link rel="manifest" href="/manifest.json">
å¤å¶ä»£ç
{
"name" : "Minimal PWA" ,
"short_name" : "PWA Demo" ,
"display" : "standalone" ,
"start_url" : "/" ,
"theme_color" : "#313131" ,
"background_color" : "#313131" ,
"icons" : [
{
"src": "images/touch/homescreen48.png",
"sizes": "48x48",
"type": "image/png"
}
]
}
å¤å¶ä»£ç
éè¿ä¸ç³»åé ç½®ï¼å°±å¯ä»¥æä¸ä¸ªPWAåAPPä¸æ ·ï¼æ·»å ä¸ä¸ªå¾æ å°ææºå±å¹ä¸ï¼ç¹å»å¾æ å³å¯æå¼ç«ç¹
åºäºwebpackçreactå¼åç¯å¢
æ¬æé»è®¤ä½ å·²ç»äºè§£æåºæ¬çwebpacké ç½®ï¼å¦æå®å ¨ä¸ä¼ï¼å»ºè®®çä¸è¿ç¯æç«
æ们é¦å æ建ä¸ä¸ªæç®åçåºäºwebpackçreactå¼åç¯å¢
æºä»£ç å°åï¼github.com/deepred5/leâ¦
mkdir learn-dll
cd learn-dll
å¤å¶ä»£ç
å®è£ ä¾èµ
npm init -y
npm install @babel/polyfill react react-dom --save
å¤å¶ä»£ç
npm install webpack webpack-cli webpack-dev-server @babel/core @babel/preset-env @babel/preset-react add-asset-html-webpack-plugin autoprefixer babel-loader clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin node-sass postcss-loader sass-loader style-loader --save-dev
å¤å¶ä»£ç
æ°å»º.bablerc
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage", // æ ¹æ®browsersliså¡«åçæµè§å¨ï¼èªå¨æ·»å polyfill
"corejs": 2,
}
],
"@babel/preset-react" // ç¼è¯react
],
"plugins": []
}
å¤å¶ä»£ç
æ°å»ºpostcss.config.js
module.exports = {
plugins: [
require('autoprefixer') // æ ¹æ®browsersliså¡«åçæµè§å¨ï¼èªå¨æ·»å cssåç¼
]
}
å¤å¶ä»£ç
æ°å»º.browserslistrc
last 10 versions
ie >= 11
ios >= 9
android >= 6
å¤å¶ä»£ç
æ°å»ºwebpack.dev.js
(åºæ¬é
ç½®ä¸å详ç»ä»ç»)
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].js',
chunkFilename: '[name].chunk.js',
},
devServer: {
historyApiFallback: true,
overlay: true,
port: 9001,
open: true,
hot: true,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.css$/,
use: ['style-loader',
'css-loader',
'postcss-loader'
],
},
{
test: /\.scss$/,
use: ['style-loader',
{
loader: 'css-loader',
options: {
modules: false,
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
],
},
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }), // indexæå
模æ¿
]
}
å¤å¶ä»£ç
æ°å»ºsrc
ç®å½ï¼å¹¶æ°å»ºsrc/index.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>learn dll</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
å¤å¶ä»£ç
æ°å»ºsrc/Home.js
import React from 'react';
import './Home.scss';
export default () => <div className="home">home</div>
å¤å¶ä»£ç
æ°å»ºsrc/Home.scss
.home {
color: red;
}
å¤å¶ä»£ç
æ°å»ºsrc/index.js
import React, { Component } from 'react';
import ReactDom from 'react-dom';
import Home from './Home';
class Demo extends Component {
render() {
return (
<Home />
)
}
}
ReactDom.render(<Demo/>, document.getElementById('app'));
å¤å¶ä»£ç
ä¿®æ¹package.json
"scripts": {
"dev": "webpack-dev-server --config webpack.dev.js"
},
å¤å¶ä»£ç
æåï¼è¿è¡npm run dev
ï¼åºè¯¥å¯ä»¥çè§ææ
æ°å»ºwebpack.prod.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'production',
entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].[contenthash:8].js',
chunkFilename: '[name].[contenthash:8].chunk.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, // åç¬æåcssæ件
'css-loader',
'postcss-loader'
],
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: false,
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
],
},
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css',
chunkFilename: '[id].[contenthash:8].css',
}),
new CleanWebpackPlugin(), // æå
åå
å é¤ä¹åçdistç®å½
]
};
å¤å¶ä»£ç
ä¿®æ¹package.json
ï¼æ·»å ä¸å¥"build": "webpack --config webpack.prod.js"
è¿è¡npm run build
ï¼å¯ä»¥çè§æå
åºæ¥çdist
ç®å½
html,js,cssé½åç¬å离åºæ¥äº
è³æ¤ï¼ä¸ä¸ªåºäºwebpackçreactç¯å¢æ建å®æ
webpack-manifest-plugin
é常æ
åµä¸ï¼æ们æå
åºæ¥çjs,cssé½æ¯å¸¦ä¸çæ¬å·çï¼éè¿HtmlWebpackPlugin
å¯ä»¥èªå¨å¸®æ们å¨index.html
éé¢å ä¸å¸¦çæ¬å·çjsåcss
<!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>learn dll</title>
<link href="main.198b3634.css" rel="stylesheet"></head>
<body>
<div id="app"></div>
<script type="text/javascript" src="main.d312f172.js"></script></body>
</html>
å¤å¶ä»£ç
ä½æ¯å¨æäºæ
åµï¼index.html
模æ¿ç±å端渲æï¼é£ä¹æ们就éè¦ä¸ä»½æå
æ¸
åï¼ç¥éæå
åçæ件对åºççæ£è·¯å¾
å®è£
æ件webpack-manifest-plugin
npm i webpack-manifest-plugin -D
ä¿®æ¹webpack.prod.js
const ManifestPlugin = require('webpack-manifest-plugin');
module.exports = {
// ...
plugins: [
new ManifestPlugin()
]
};
å¤å¶ä»£ç
éæ°æå
ï¼å¯ä»¥çè§dist
ç®å½æ°çæäºä¸ä¸ªmanifest.json
{
"main.css": "main.198b3634.css",
"main.js": "main.d312f172.js",
"index.html": "index.html"
}
å¤å¶ä»£ç
æ¯å¦å¨SSRå¼åæ¶ï¼å端æå åï¼nodeå端就å¯ä»¥éè¿è¿ä¸ªjsonæ°æ®ï¼è¿åæ£ç¡®èµæºè·¯å¾çhtml模æ¿
const buildPath = require('./dist/manifest.json');
res.send(`
<!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>ssr</title>
<link href="${buildPath['main.css']}" rel="stylesheet"></head>
<body>
<div id="app"></div>
<script type="text/javascript" src="${buildPath['main.js']}"></script></body>
</html>
`);
å¤å¶ä»£ç
代ç åå²
æ们ä¹åçæå
æ¹å¼ï¼æä¸ä¸ªç¼ºç¹ï¼å°±æ¯æä¸å¡ä»£ç ååºä»£ç é½ç»ç»æå°äºä¸ä¸ªmain.js
éé¢ãæ¯æ¬¡ä¸å¡ä»£ç æ¹å¨åï¼main.js
çhashå¼å°±åäºï¼å¯¼è´å®¢æ·ç«¯åè¦éæ°ä¸è½½ä¸émain.js
ï¼ä½æ¯éé¢çåºä»£ç å
¶å®æ¯æ²¡æ¹åçï¼
é常æ
åµä¸ï¼react
react-dom
ä¹ç±»çåºï¼é½æ¯ä¸ç»å¸¸æ¹å¨çãæ们å¸æåç¬æè¿äºåºä»£ç æååºæ¥ï¼çæä¸ä¸ªvendor.js
ï¼è¿æ ·æ¯æ¬¡æ¹å¨ä»£ç ï¼åªæ¯ä¸è½½main.js
ï¼vendor.js
å¯ä»¥å
åç¼å(ä¹å°±æ¯æè°ç代ç åå²code splitting)
webpack4èªå¸¦ä»£ç åå²åè½ï¼åªè¦é ç½®:
optimization: {
splitChunks: {
chunks: 'all'
}
}
å¤å¶ä»£ç
webpack.prod.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
module.exports = {
mode: 'production',
entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].[contenthash:8].js',
chunkFilename: '[name].[contenthash:8].chunk.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
],
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: false,
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
],
},
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css',
chunkFilename: '[id].[contenthash:8].css',
}),
new CleanWebpackPlugin(),
new ManifestPlugin()
],
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
å¤å¶ä»£ç
éæ°æå
ï¼åç°æ°çæäºä¸ä¸ªvendor.js
æ件ï¼å
¬ç¨çä¸äºä»£ç 就被æå
è¿å»äº
éæ°ä¿®æ¹src/Home.js
,ç¶åæå
ï¼ä½ ä¼åç°vendor.js
çhash没ææ¹åï¼è¿ä¹æ¯æ们å¸æç
DLLæå
ä¸é¢çæå
æ¹å¼ï¼éç项ç®çå¤æ度ä¸ååï¼æå
é度ä¼å¼å§åæ
¢ãåå æ¯ï¼æ¯æ¬¡æå
ï¼webpacké½è¦åæåªäºæ¯å
¬ç¨åºï¼ç¶åæä»æå
å°vendor.js
é
æ们å¯ä¸å¯ä»¥å¨ç¬¬ä¸æ¬¡æ建vendor.js
以åï¼ä¸æ¬¡æå
ï¼å°±ç´æ¥è·³è¿é£äºè¢«æå
å°vendor.js
éç代ç å¢ï¼è¿æ ·æå
é度å¯ä»¥ææ¾æå
è¿å°±éè¦DllPlugin
ç»åDllRefrencePlugin
æ件çè¿ç¨
dllæå åçå°±æ¯ï¼
- ææå®çåºä»£ç æå
å°ä¸ä¸ª
dll.js
,åæ¶çæä¸ä»½å¯¹åºçmanifest.json
æ件 - webpackæå
æ¶ï¼è¯»å
manifest.json
,ç¥éåªäºä»£ç å¯ä»¥ç´æ¥å¿½ç¥ï¼ä»èæé«æ建é度
æ们æ°å»ºä¸ä¸ªwebpack.dll.js
const path = require('path');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'production',
entry: {
vendors: ['react', 'react-dom'] // æå¨æå®æå
åªäºåº
},
output: {
filename: '[name].[hash:8].dll.js',
path: path.resolve(__dirname, './dll'),
library: '[name]'
},
plugins: [
new CleanWebpackPlugin(),
new webpack.DllPlugin({
path: path.join(__dirname, './dll/[name].manifest.json'), // çæ对åºçmanifest.jsonï¼ç»webpackæå
ç¨
name: '[name]',
}),
],
}
å¤å¶ä»£ç
æ·»å ä¸æ¡å½ä»¤:
"build:dll": "webpack --config webpack.dll.js"
è¿è¡dllæå
npm run build:dll
åç°çæä¸ä¸ªdll
ç®å½
ä¿®æ¹webpack.prod.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const webpack = require('webpack');
module.exports = {
mode: 'production',
entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].[contenthash:8].js',
chunkFilename: '[name].[contenthash:8].chunk.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
],
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: false,
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
],
},
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css',
chunkFilename: '[id].[contenthash:8].css',
}),
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, './dll/vendors.manifest.json') // 读ådllæå
åçmanifest.jsonï¼åæåªäºä»£ç è·³è¿
}),
new CleanWebpackPlugin(),
new ManifestPlugin()
],
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
å¤å¶ä»£ç
éæ°npm run build
ï¼åç°dist
ç®å½éï¼vendor.js
没æäº
è¿æ¯å 为react
,react-dom
å·²ç»æå
å°dll.js
éäºï¼webpack
读åmanifest.json
ä¹åï¼ç¥éå¯ä»¥å¿½ç¥è¿äºä»£ç ï¼äºæ¯å°±æ²¡æåæå
äº
ä½è¿éè¿æ个é®é¢ï¼æå
åçindex.html
è¿éè¦æ·»å dll.js
æ件ï¼è¿å°±éè¦add-asset-html-webpack-plugin
æ件
npm i add-asset-html-webpack-plugin -D
ä¿®æ¹webpack.prod.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const webpack = require('webpack');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
module.exports = {
mode: 'production',
entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].[contenthash:8].js',
chunkFilename: '[name].[contenthash:8].chunk.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
],
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: false,
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
],
},
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new AddAssetHtmlPlugin({ filepath: path.resolve(__dirname, './dll/*.dll.js') }), // ædll.jså è¿index.htmléï¼å¹¶ä¸æ·è´æ件å°distç®å½
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css',
chunkFilename: '[id].[contenthash:8].css',
}),
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, './dll/vendors.manifest.json') // 读ådllæå
åçmanifest.jsonï¼åæåªäºä»£ç è·³è¿
}),
new CleanWebpackPlugin(),
new ManifestPlugin()
],
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
å¤å¶ä»£ç
éæ°npm run build
ï¼å¯ä»¥çè§dll.js
ä¹è¢«æå
è¿dist
ç®å½äºï¼åæ¶index.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>learn dll</title>
<link href="main.198b3634.css" rel="stylesheet"></head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vendors.8ec3d1ea.dll.js"></script><script type="text/javascript" src="main.0bc9c924.js"></script></body>
</html>
å¤å¶ä»£ç
å°ç»
æ们ä»ç»äº4ç§manifest
ç¸å
³çå端ææ¯ãmanifest
çè±æå«ä¹æ¯åå, 4ç§ææ¯çç¡®é½æ¯æmanifest
å½åæ¸
å使ç¨ï¼
- ç¼åæ¸ å
- PWAæ¸ å
- æå èµæºè·¯å¾æ¸ å
- dllæå æ¸ å
åªä¸è¿æ¯å¨ä¸åçåºæ¯ä¸ä½¿ç¨ç¹å®çæ¸ åæ¥å®ææäºåè½
æ以ï¼å¦å¥½è±ææ¯å¤ä¹éè¦ï¼è¿æ ·æä¸ä¼å»å»åä¸æ¸
manifest
å°åºæ¯å¹²å¥çï¼