Proxy 是 ES6 中新增的功能,它可以用来自定义对象中的操作。 Vue3.0 中将会通过 Proxy 来替换原本的 Object.defineProperty 来实现数据响应式。
let p = new Proxy(target, handler);
target
代表需要添加代理的对象,handler
用来自定义对象中的操作,比如可以用来自定义 set 或者 get 函数。
let onWatch = (obj, setBind, getLogger) => { let handler = { set(target, property, value, receiver) { setBind(value, property); return Reflect.set(target, property, value); }, get(target, property, receiver) { getLogger(target, property); return Reflect.get(target, property, receiver); }, }; return new Proxy(obj, handler); }; let obj = { a: 1 }; let p = onWatch( obj, (v, property) => { console.log(`监听到属性${property}改变为${v}`); }, (target, property) => { console.log(`'${property}' = ${target[property]}`); } ); p.a = 2; // 控制台输出:监听到属性a改变 p.a; // 'a' = 2
因为可以自定义 Hooks, 我们可以非常方便的复用状态逻辑。
// 定时器DEMO function useCount(defaultCount) { const [count, setCount] = useState(defaultCount); const timer = useRef(); useEffect(() => { timer.current = setInterval(() => { setCount((count) => count + 1); }, 1000); }, []); useEffect(() => { if (count >= 10) { clearInterval(timer.current); } }); return [count]; } function App() { const [count] = useCount(0); return ( <> <h1>count: {count}</h1> </> ); }
webpack.config.js 是 webpack 的默认打包配置文件。也可以npx webpack --config 配置文件名
手动设置
/** * Wepack配置接口 */ const path = require("path"); module.exports = { // 打包模式 mode: "production", // 入口 entry: "./index.js", // 出口 output: { filename: "bundle.js", // path 后必须是一个绝对位置 path: path.resolve(__dirname, "bundle"), }, };
其中entry: "./index.js"
是一个简写,
entry: { main: "./index.js" }
hash 一般是结合 CDN 缓存来使用,通过 webpack 构建之后,生成对应文件名自动带上对应的 MD5 值。如果文件内容改变的话,那么对应文件哈希值也会改变,对应的 HTML 引用的 URL 地址也会改变,触发 CDN 服务器从源服务器上拉取对应数据,进而更新本地缓存。但是在实际使用的时候,这几种 hash 计算还是有一定区别。
hash
hash 是跟整个项目的构建相关,只要项目里有文件更改,整个项目构建的 hash 值都会更改,并且全部文件都共用相同的 hash 值
chunkhash
采用 hash 计算的话,每一次构建后生成的哈希值都不一样,即使文件内容压根没有改变。这样子是没办法实现缓存效果,我们需要换另一种哈希值计算方式,即 chunkhash。 chunkhash 和 hash 不一样,它根据不同的入口文件(Entry)进行依赖文件解析、构建对应的 chunk,生成对应的哈希值。我们在生产环境里把一些公共库和程序入口文件区分开,单独打包构建,接着我们采用 chunkhash 的方式生成哈希值,那么只要我们不改动公共库的代码,就可以保证其哈希值不会受影响。
contenthash
在使用 chunkhash 的例子中,如果 index.css 被 index.js 引用了,那么就会共用相同的 chunkhash 值。但是这样子有个问题,如果 index.js 更改了代码,css 文件就算内容没有任何改变,由于是该模块发生了改变,导致 css 文件会重复构建。
这个时候,我们可以使用 extra-text-webpack-plugin 里的 contenthash 值,保证即使 css 文件所处的模块里就算其他文件内容改变,只要 css 文件内容不变,那么不会重复构建。
Source map 就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。
源文件
function sayHello(name) { if (name.length > 2) { name = name.substr(0, 1) + "..."; } console.log("hello,", name); }
压缩后
function sayHello(name) { if (name.length > 2) { name = name.substr(0, 1) + "..."; } console.log("hello,", name); } sayHello("世界"); sayHello("第三世界的人们");
map 文件
{"version":3,"sources":["log.js","main.js"],"names":["sayHello","name","length","substr","console","log"],"mappings":"AAAA,SAASA,SAASC,MACd,GAAIA,KAAKC,OAAS,EAAG,CACjBD,KAAOA,KAAKE,OAAO,EAAG,GAAK,MAE/BC,QAAQC,IAAI,SAAUJ,MCJ1BD,SAAS,MACTA,SAAS"}