debugger Android ios webview (调试 app webview)

webpack 开启本地服务,host 设置 0.0.0.0 端口最好是80(mac 开启本地服务需要加sudo使用80端口)
Charles 设置 proxy 端口(默认8888) 设置DNS Spoofing 把需要的域名如: m.baidu.com指向0.0.0.0
手机 wifi 设置代理 电脑ip:8888

完成, app H5 页面的m.baidu.com的服务就是电脑webpack 的服务

调试工具:
android 可以通过 chrome devtool 调试,usb 连接手机, devtool 找到 remote devices
ios 电脑safari devtool, 手机safari 开启 web inspector, mac 打开 safari 调试
ios safari 通过 chrome 调试的方法 https://github.com/RemoteDebug/remotedebug-ios-webkit-adapter

2 charles 设置代理
ios safari 输入localhost 不能被转发 可以输入 localhost. 或 http://localhost.charlesproxy.com/ 代替localhost

3 通过 手机 浏览器 访问本地服务器
1 在您的开发计算机与 Android 设备之间设置远程调试。 完成后,您应在 Inspect Devices 对话框的左侧菜单中看到 Android 设备,还应看到 Connected 状态指示器。

2 在 DevTools 的 Inspect Devices 对话框中,启用 Port forwarding。
3 在左侧的 Device port 文本字段中,输入 Android 设备上您想要从其访问网站的 localhost 端口号。例如,如果您想要从 localhost:5000 访问网站,则应输入 5000。
4 在右侧的 Local address 文本字段中,输入开发计算机网络服务器上运行的您的网站的 IP 地址或主机名,后面紧跟端口号。例如,如果您的网站在 localhost:7331 上运行,则应输入 localhost:7331。
5 可以device port 可以和服务器端口一样,这样可以解决一些问题端口不同问题
https://developers.google.com/web/tools/chrome-devtools/remote-debugging/local-server#port-forwarding

css 新属性

pointer-events
实际代码使用中案例:
1、提交页面,提交按钮点击后,添加这个样式属性(style=”pointer-events”),来防止重复提交
2、一些层的绝对定位,覆盖按钮,穿透可以点击它。等等。

pointer-events属性值详解
auto——效果和没有定义pointer-events属性相同,鼠标不会穿透当前层。在SVG中,该值和visiblePainted的效果相同。

none——元素不再是鼠标事件的目标,鼠标不再监听当前层而去监听下面的层中的元素。但是如果它的子元素设置了pointer-events为其它值,比如auto,鼠标还是会监听这个子元素的。

width/hight: fill-available 撑满可用空间;fit-content 元素宽度缩小到内容的宽度;max-content 宽度根据内容最大宽度、min-content 根据内容最小宽度

3. filter 增加滤镜属性

可以实现 图片模糊,去色,

/* URL to SVG filter */
filter: url("filters.svg#filter-id");

/* <filter-function> values */
filter: blur(5px);
filter: brightness(0.4);
filter: contrast(200%);
filter: drop-shadow(16px 16px 20px blue);
filter: grayscale(50%);
filter: hue-rotate(90deg);
filter: invert(75%);
filter: opacity(25%);
filter: saturate(30%);
filter: sepia(60%);

/* Multiple filters */
filter: contrast(175%) brightness(3%);

preload 和 prefetch

preload 是告诉浏览器页面必定需要的资源,浏览器一定会加载这些资源
prefetch 是告诉浏览器页面可能需要的资源,浏览器不一定会加载这些资源
prefetch ,它的作用是告诉浏览器加载下一页面可能会用到的资源,注意,是下一页面,而不是当前页面。因此该方法的加载优先级非常低,也就是说该方式的作用是加速下一个页面的加载速度

preload 好处:
1、将加载和执行分离开,不阻塞渲染和document的onload事件
2、提前加载指定资源,不再出现依赖的font字体隔了一段时间才刷出的情况
3、Preload 有 as 属性,浏览器可以设置正确的资源加载优先级,这种方式可以确保资源根据其重要性依次加载, 所以,Preload既不会影响重要资源的加载,又不会让次要资源影响自身的加载;浏览器能根据 as 的值发送适当的 Accept 头部信息;浏览器通过 as 值能得知资源类型,因此当获取的资源相同时,浏览器能够判断前面获取的资源是否能重用
4、如果忽略 as 属性,或者错误的 as 属性会使 preload 等同于 XHR 请求,浏览器不知道加载的是什么,因此会赋予此类资源非常低的加载优先级

preload 二次获取
1、如果对所 preload 的资源不使用明确的 “as” 属性,将会导致二次获取
2、 preload 字体不带 crossorigin 会二次获取! 确保对 preload 的字体添加 crossorigin 属性,否则字体文件会被下载两次,这个请求使用匿名的跨域模式。这个建议也适用于字体文件在相同域名下,也适用于其他域名的获取(比如说默认的异步获取)

webpack
webpack 4.6.0+ adds support for prefetching and preloading.

1 preload 加载平行于 主要加载项目, prefetch 在主要加载项完成后加载
2 preload 中等优先度,会立即下载, prefetch 会在空闲(idle)时下载
3 preload 内容 通过 父chunk 会被立即用到, prefetch 内容会在将来用到

prefetch 案例: HomePage component 里有 LoginBotton component , 点击 按钮是会加载LoginModal
LoginButton.js
[cc lang=”js”]import(/* webpackPrefetch: true */ ‘LoginModal’);[/cc]

result in

prelaod 案例: ChartComponent 需要 比较大的 ChartingLibrary, 加载完页面就需要用到ChartingLibrary 里的 LoadingIndicator
ChartComponent.js
[cc lang=”js”]import(/* webpackPreload: true */ ‘ChartingLibrary’);[/cc]

https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf
https://medium.com/webpack/link-rel-prefetch-preload-in-webpack-51a52358f84c

vue cli3.0 分离常用库和 在页面head 注入cdn

[cc lang=”javascript”]
const path = require(‘path’);
const CompressionWebpackPlugin = require(‘compression-webpack-plugin’);
const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin’);
const productionGzipExtensions = [‘js’, ‘css’];
const isProduction = process.env.NODE_ENV === ‘production’;

function resolve(dir) {
return path.join(__dirname, dir);
}

// 预发布环境
const isLocalBuild = process.env.IS_LOCAL_BUILD === ‘isLocalBuild’;
console.log(‘前端文件预发布打包- isLocalBuild:’, isLocalBuild);

// 非externals CND前缀设置
const CDN_URL = isLocalBuild ? ‘/’ : ‘//s.zypj.nasetech.com/’;

// 区分生产环境打包和预发布打包,使用不同的CDN
const JS_CDN = isLocalBuild ? [
// 预发布CDN
] : [
// 生产CDN
];

const cdn = {
// css: [],
js: JS_CDN
}

module.exports = {
lintOnSave: true,
baseUrl: isProduction ? CDN_URL : ‘/’,
chainWebpack: (config) => {
// build打包才使用CDN
if (isProduction) {
config.plugin(‘html’)
.tap(args => {
args[0].cdn = cdn;
return args;
})
}

config.resolve.alias
.set(‘assets’, resolve(‘src/assets’))
.set(‘pages’, resolve(‘src/pages’))
.set(‘components’, resolve(‘src/components’))
.set(‘utils’, resolve(‘src/utils’))
},
devServer: {
host: ‘0.0.0.0’,
port: 8080,
https: false,
hotOnly: false,
disableHostCheck: false,
proxy: {
‘/api/v0/’: {
// 目标 API 地址
target: ‘http://127.0.0.1:4545’,
// 将主机标头的原点更改为目标URL
changeOrigin: true,
},
},
},
configureWebpack: config => {
// 生产模式
if (isProduction) {
config.externals = {
‘vue’: ‘Vue’,
‘vue-router’: ‘VueRouter’,
‘moment’: ‘moment’
}
// 打包生产.gz包
config.plugins.push(new CompressionWebpackPlugin({
algorithm: ‘gzip’,
test: new RegExp(‘\\.(‘ + productionGzipExtensions.join(‘|’) + ‘)$’),
threshold: 10240,
minRatio: 0.8
}))
// 添加自定义代码压缩配置
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false,
drop_debugger: true,
drop_console: true,
},
},
sourceMap: false,
parallel: true,
})
)
}
}
}[/cc]