We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
每次代码需要更新时,服务器必须重新部署,客户端也必须重新下载资源。因为从网络中获取资源会很慢,这显然非常低效。这就是为什么浏览器会缓存静态资源的原因。但是这样做有一个弊端:如果在部署新的版本中不修改文件名,浏览器会认为它没有更新,就会使用缓存中的版本。
webpack通过hash配置可以帮我们构建出文件名不同的静态资源文件,这样浏览器就能获取到最新的静态资源了。但是这样每次浏览器对静态资源的请求是全量的,如果可以只修改发生变化的文件的hash值,这样就能进行增量请求,可以大大提高我们的web性能,这就我们所说的持久化缓存。
##(搭建webpack过程)
npm init //全局安装 npm install -g webpack //安装到你的项目目录 npm install --save-dev webpack
1.在空目录下新建两个文件
将webpack.config.js拆分为webpack.development.config.js、webpack.production.config.js。【在webpack4中,添加了mode('development','production','none')配置项,同时会自动同步process.env.NODE_ENV的值。】(同命令行 --mode development)
webpack.development.config.js
module.exports = { mode: 'deveopment', entry: __dirname + "/src/index.js", //入口 output: { //出口 path:__dirname + "/public", filename: "bundle.js" }, devtool:'eval-source-map' //使得编译后的代码可读性更高,也更容易调试 }
webpack.production.config.js
module.exports = { mode:'production', entry: __dirname + "/src/index.js", //入口 output: { //出口 path:__dirname + "/public", filename: "bundle.js" }, devtool:'source-map' //使得编译后的代码可读性更高,也更容易调试 }
package.json 修改为:
{ "name": "document", "version": "1.0.0", "description": "", "main": "webpack.development.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack --mode development --config webpack.development.config.js", "build": "webpack --mode production --config webpack.production.config.js" }, "author": "", "license": "ISC" }
2.在空目录下新建public,src目录 index.html 放在public目录下
<!-- index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Webpack Sample Project</title> </head> <body> <div id='root'> </div> <script src="bundle.js"></script> </body> </html>
index.js 放在src目录下
const greeter = require('./Greeter.js'); document.querySelector("#root").appendChild(greeter());
greeter.js 放在src目录下
module.exports = function() { var greet = document.createElement('div'); greet.textContent = "Hi there and greetings!"; return greet; };
npm run start
如出现 选择webpack-cli
打包成功后,public目录打包出bundle.js,浏览器打开index.html
npm run build
.map为源码映射文件,此时查看bundle.js可以看出js代码已被压缩,因为webpack4在production环境下默认配置了压缩plugin:uglifyjs-webpack-plugin,其它默认插件有:
development环境
const webpack = require('webpack') module.exports = { mode: 'development', entry: __dirname + "/src/index.js", //入口 output: { //出口 path:__dirname + "/public", filename: "bundle.js" }, devtool:'eval-source-map', //使得编译后的代码可读性更高,也更容易调试 plugins:[ // new webpack.NamedModulesPlugin(), //已默认配置 // new webpack.NamedChunksPlugin(), //已默认配置 // new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }), //已默认配置 ] }
production环境
const webpack = require('webpack') module.exports = { mode:'production', entry: __dirname + "/src/index.js", //入口 output: { //出口 path:__dirname + "/public", filename: "bundle.js" }, devtool:'source-map', //使得编译后的代码可读性更高,也更容易调试 plugins:[ // new UglifyJsPlugin(/* ... */), //已默认配置 js压缩 // new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), //已默认配置 定义变量 // new webpack.optimize.ModuleConcatenationPlugin(), //已默认配置 作用域(scope hoisting)提升 // new webpack.NoEmitOnErrorsPlugin() //已默认配置 打包过程中报错不会退出 ] }
mode 为 none时,默认无plugin配置
npm install webpack-dev-server --save
webpack.development.config.js 添加
... devServer:{ contentBase:'./public', //设置本地服务器目录 historyApiFallback:true, //设置为true,所有的跳转将指向index.html inline:true, //实时刷新 port:3000, //端口 }, ...
package.json 添加
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack --mode development --config webpack.development.config.js", "build": "webpack --mode production --config webpack.production.config.js", "dev": "webpack-dev-server --mode development --config webpack.development.config.js --watch " },
npm run dev
浏览器打开localhost:3000 此时我们的本地服务器就构建成功了
1.添加config.json文件
{ "greetText": "Hello World!" }
2.修改greeter.js
import React, {Component} from 'react' import config from './config.json'; class Greeter extends Component{ render() { return ( <div> {config.greetText} </div> ); } } export default Greeter
3.修改index.js
import React from 'react'; import {render} from 'react-dom'; import Greeter from './greeter'; console.log(document.getElementById('root')) render(<Greeter />, document.getElementById('root'));
4.安装webpack所需loader、babel
npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-react
5.安装react所需库
npm install --save react react-dom
6.配置webpack
... module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader", options: { presets: [ "env", "react" //babel ] } }, exclude: /node_modules/ } ] } ...
此时react运行环境已配置好
1.src新建greeter.css文件
.root { background-color: #eee; padding: 100px; border: 3px solid #ccc; }
... import styles from './greeter.css'; ...
3.安装css loader
npm install css-loader style-loader
4.配置loader
... module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader", options: { presets: [ "env", "react" //babel ] } }, exclude: /node_modules/ }, { test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader", } ] } ] }, ...
可以看到css已经可以打包运行了
webpack4中已经remove了 extract-text-webpack-plugin,官方推荐使用mini-css-extract-plugin
npm install --save mini-css-extract-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); ... optimization: { minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false, // set to true if you want JS source maps uglifyOptions: { compress: true, } }), new OptimizeCSSAssetsPlugin({}) ], }, module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader", options: { presets: [ "env", "react" //babel ] } }, exclude: /node_modules/ }, { test: /\.css$/, use:[MiniCssExtractPlugin.loader,'css-loader'] } ] }, plugins[ new MiniCssExtractPlugin({ filename: "[name]-[contenthash].css", chunkFilename: "[id].css" }), ] ...
可以看到css已经被单独提取出来,并且js、css都已经被压缩
不过此时我们可以看到react仍然被打包到bundle中去了,导致bundle.js仍然很大,像这种npm包一般不会有修改,所以我们也应该提取出来 在webpack4中,commonsChunkPlugin已被removed,官方推荐使用SplitChunksPlugin
... output: { //出口 path:__dirname + "/public", filename: "[name]-[contenthash].bundle.js", chunkFilename: '[name].[chunkhash:5].chunk.js' }, ... optimization: { minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false, // set to true if you want JS source maps uglifyOptions: { compress: true, } }), new OptimizeCSSAssetsPlugin({}) ], splitChunks: { chunks: "all", //initial、async和all minSize: 30000, //形成一个新代码块最小的体积 minChunks: 1, //在分割之前,这个代码块最小应该被引用的次数 maxAsyncRequests: 5, //按需加载时候最大的并行请求数 maxInitialRequests: 3, //最大初始化请求数 automaticNameDelimiter: '~', //打包分割符 name:'commons', //打包后的名字 cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, //用于控制哪些模块被这个缓存组匹配到、它默认会选择所有的模块 priority: -10, //缓存组打包的先后优先级 name: 'vendors', minSize:3000 }, default: { minChunks: 2, priority: -20, minSize:3000 } } } }, ...
npm install html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin') ... plugins:[ ... new HtmlWebpackPlugin({ template: __dirname + "/src/index.tmpl.html",//new }), ... ] ...
src目录新建index.tmpl.html index.tmpl.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>Document</title> </head> <body> <div id="root"></div> </body> </html>
##总结
此时我们可以发现react已被打包到vendors中,bundle.js小了很多,并且多次打包,文件hash值不再修改
修改.css文件
可以发现只有css的hash值发生改变,其它文件名并未发生变化,当发布静态文件时,浏览器就对未变化的文件仍然使用缓存,这样就符合我们要实现持久化缓存的预期。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
之前一直对webpack只是了解到一些皮毛,最近抽空学习了一些持久化缓存的必要性以及方案,并自己进行了一次从0到1的项目配置,花了几天的的时间梳理了一下,在此写下分享,方便大家一起交流学习,有写错或理解错的地方还请大佬多多指点。
开题
1. 缓存的作用
2.webpack配置持久化缓存解决问题
开始构建过程
##(搭建webpack过程)
1.安装webpack
2.新建文件配置文件及打包项目
1.在空目录下新建两个文件
webpack.development.config.js
webpack.production.config.js
package.json 修改为:
2.在空目录下新建public,src目录
index.html 放在public目录下
index.js 放在src目录下
greeter.js 放在src目录下
3.command -1及plugin配置
如出现
选择webpack-cli
.map为源码映射文件,此时查看bundle.js可以看出js代码已被压缩,因为webpack4在production环境下默认配置了压缩plugin:uglifyjs-webpack-plugin,其它默认插件有:
mode 为 none时,默认无plugin配置
4.构建本地服务器
webpack.development.config.js 添加
package.json 添加
浏览器打开localhost:3000
此时我们的本地服务器就构建成功了
5.现在我们尝试配置react开发环境,添加loader、babel对文件内容进行处理 (development、production公用配置)
1.添加config.json文件
2.修改greeter.js
3.修改index.js
4.安装webpack所需loader、babel
5.安装react所需库
6.配置webpack
此时react运行环境已配置好
6.配置css运行环境(development、production公用配置)
1.src新建greeter.css文件
2.修改greeter.js
3.安装css loader
4.配置loader
持久化缓存优化 (一般production才配置)
1.提取css并压缩
2.配置
3.提取公共模块
4.配置化生成index.html (自动更新导入的css、js文件)
5.查看成果
##总结
The text was updated successfully, but these errors were encountered: