标签:plugin sse nbsp ons top doctype loader text webpack
需要两步来实现:
下载插件并配置:
npm i px2rem-loader lib-flexible module: { rules: [ { test: /\.less$/, use: [ MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", ... }, { loader: "px2rem-loader", options: { remUnit: 75, remPrecision: 8 } }, "less-loader", ] }, ] },
然后,需要将淘宝的插件的内联在html文件中:
<script src=‘../node_modules/lib-flexible/flexible.js‘></script>
静态资源内联是指将CSS、JS等静态文件中的内容抽离出来,内联到html中。我们之前借助插件做到了将内联的资源独立成文件,为什么还要将资源内联呢?
资源内联的意义:
HTML和JS内联
使用raw-loader,注意要使用0.5的版本,新版本的存在一些问题。
npm i raw-loader@0.5.1 /src/meta.html 【例:腾讯NOW直播官网的meta标签】 <meta charset="UTF-8"> <meta name="viewport" content="viewport-fit=cover,width=device-width,initial-scale=1,user-scalable=no"> <meta name="format-detection" content="telephone=no"> <meta name="keywords" content="now,now直播,直播,腾讯直播,QQ直播,美女直播,附近直播,才艺直播,小视频,个人直播,美女视频,在线直播,手机直播"> <meta name="name" itemprop="name" content="NOW直播—腾讯旗下全民视频社交直播平台"> <meta name="description" itemprop="description" content="NOW直播,腾讯旗下全民高清视频直播平台,汇集中外大咖,最in网红,草根偶像,明星艺人,校花,小鲜肉,逗逼段子手,各类美食、音乐、旅游、时尚、健身达人与你24小时不间断互动直播,各种奇葩刺激的直播玩法,让你跃跃欲试,你会发现,原来人人都可以当主播赚钱!"> <meta name="image" itemprop="image" content="https://pub.idqqimg.com/pc/misc/files/20170831/60b60446e34b40b98fa26afcc62a5f74.jpg"> <meta name="baidu-site-verification" content="G4ovcyX25V"> <meta name="apple-mobile-web-app-capable" content="no"> <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> /node_modules/lib-flexible/flexible.js 【npm下载的淘宝库】 /src/index.html <!DOCTYPE html> <html lang="en"> <head> ${ require(‘raw-loader!./meta/meta.html‘) } <title>Hello Webpack</title> <script>${ require(‘raw-loader!babel-loader!../node_modules/lib-flexible/flexible.js‘) }</script> <!-- 先用raw-loader内联,再用babel-laoder转换语法 --> </head> <body> <div id="root"></div> </body> </html>
CSS内联
借助style-loader即可
{ loader: ‘style-loader‘, options: { insertAt: ‘top‘, // 样式插入到<head> singleton: true, // 将所有style标签合并成一个 } }
每当增加一个页面,我们就手动地在webapck配置中对应增加一个entry、html-webpack-plugin。
一定可以有更优的方案,那就是:动态获取entry的数量、然后自动生成html-webpack-plugin。
需要借助glob.sync,可以在每次构建的时候获取页面的数量。这需要我们规范目录,将每个页面(文件夹)都放在src文件夹下,每个页面(文件夹)入口文件是index.js,入口页面是index.html。
npm i glob const glob = require(‘glob‘); const setMPA = () => { let entry = {}; let htmlWebpackPlugins = []; const entryFiles = glob.sync(path.join(__dirname, ‘./src/*/index.js‘)); // 获取所有页面的入口文件路径。entryFiles是所有页面index.js的绝对路径形成的数组 entryFiles.forEach((file)=>{ let name = file.match(/src\/(.*)\/index\.js/); let pageName = name && name[1]; entry[pageName] = file; htmlWebpackPlugins.push(new HtmlWebpackPlugin({ template: file.replace("index.js","index.html"), filename: `${pageName}.html`, chunks: [`${pageName}`], inject: true, minify: { html5: true, collapseWhitespace: true, preserveLineBreaks: false, minifyCSS: true, minifyJS: true, removeComments: true, }, })) }); return { entry, htmlWebpackPlugins } }; const result = setMPA(); module.exports = { entry: result.entry, output: { filename: "bundle[chunkhash:8].js", path: path.join(__dirname, "/dist") }, mode: ‘production‘, module: { rules: [ ... ] }, plugins: [ ...result.htmlWebpackPlugins, // 将N个HtmlWebpackPlugin对象插入列表 new MiniCssExtractPlugin({ filename: ‘[name][contenthash:8].css‘ }), new OptimizeCssAssetsPlugin({ assetNameRegExp: /\.css$/g, cssProcessor: require(‘cssnano‘), }), new CleanWebpackPlugin(), };
什么是source map?顾名思义,就是代码地图,可以将构建前后的两份代码做一个映射。
sourcemap的作用:构建后的代码已经变了模样,没有可读性,开发调试的时候无法定位问题所在。sourcemap的存在可以直接将问题定位到源代码,排查问题。
配置文件中devtool属性可以设置,有非常多的类型可选,一般情况下,开发环境使用"source-map",生产环境关闭。
module.exports = { devtool: "source-map" };
对于大型的web应用来说,将所有的代码编译成一个文件显示不好,会造成文件体积过大以及需要加载大量与首屏无关的代码,用户体验不好。webpack提供将代码分割成chunk(语块),当代码运行到需要的它们的时候再进行加载。
代码分割有两种类型:
需要借助插件,有两个插件可供选择:html-webpack-externals-plugin 和 SplitChunsPlugin(webpack4内置,代替webpack3的CommonsChunkPlugin)
说明:
html-webpack-externals-plugin:
npm i html-webpack-externals-plugin const HtmlWebpackExternalsPlugin = require(‘html-webpack-externals-plugin‘); plugins: [ new HtmlWebpackExternalsPlugin({ externals: [ { module: "react", // 代码中引入的库的名称 entry: "https://11.url.cn/now/lib/16.2.0/react.min.js", // entry: "cjs/react", // 相对于node_modules/react的路径【官网示例,实际并不成功】 global: "React", // 代码中引入的库的全局对象的名称 }, { module: "react-dom", entry: "https://11.url.cn/now/lib/16.2.0/react-dom.min.js", // entry: "dist/react-dom", // 相对于node_modules/react-dom的路径 【官网示例,实际并不成功】 global: "ReactDOM", }, ], }) ]
SplitChunksPlugin:
module.exports = { optimization: { splitChunks: { minSize: 0, // 分离包体积的最小大小 cacheGroups: { commons: { // test: /(react|react-dom)/, // 通过正则匹配,只分离react/react-dom这两个库,不写test则不作限制 name: ‘commonss‘, // 分离块的名称,需要加在HtmlWebpackPlugin插件的chunks属性中,才能正确命名分离后的文件 chunks: "all", // 需要分割哪些代码块,all表示所有代码块,async按需加载的代码块,initial初始化代码块 // minChunks: 2, // 最小引用次数,少于这个引用次数就不会单独提取出来 } } } } };
实现懒加载不需要对webpack配置,动态引入import(‘‘)语法还没有成为JS标准(也许不久的将来会),目前要借助js插件
实现懒加载:
npm i @babel/plugin-syntax-dynamic-import .babelrc { "presets": [ "@babel/preset-react", "@babel/preset-env" ], "plugins": [ "@babel/plugin-syntax-dynamic-import", // 懒加载插件 "@babel/plugin-proposal-class-properties" ] }
在此基础上,如果使用React开发项目,还可以使用react-loadable插件来更好的实现异步加载
npm i react-loadable index.js中部分代码 import Loadable from "react-loadable"; const TextLoad = Loadable({ loader: () => import(/* webpackChunkName: ‘text‘ */ ‘./text‘), // 通过注释的方式指定打包后的chunk的名字 loading: ()=> <div>正在加载</div> }); class Search extends React.Component{ constructor(props){ super(props); this.state = { text: false, }; } loadComponent = () => { this.setState({ text: true }) }; render() { const { text } = this.state; return ( <> <div>你好,显示字体 Hello Webpacks</div> { text ? <TextLoad /> : null } <img src={logo} style={{ width: 100 }} onClick={this.loadComponent}/> </> ) } } export default Search;
一个文件会有多个方法、对象、语句,只要用到其中一小部分,便会将整个文件内的所有内容打包进去。tree shaking只把用到的方法打包进去,没用到的会在uglfiy阶段被擦出掉。
使用:webpack默认支持,生产环境默认开启
要求:必须是ES6的写法,CommonJS的方式不支持
构建之后的代码存在大量闭包,导致:
scope hoisting就是减少闭包函数的声明。
原理:将所有模块的代码按照引用顺序放在一个函数作用域里,然后适当地重命名一些变量以防止变量名冲突,以此减少闭包函数声明代码。
使用:webpack默认支持,生产环境默认开启
要求:必须是ES6写法,CommonJS的方式不支持
每次构建,命令行输出大量日志,有很多是我们完全不关心的,想要优化它,可以在webpack中设置state属性。
// 如果是打包,在最外层的state属性 module.exports = { stats: ‘errors-only‘, }; // 如果是devserver热更新 const devConfig = { devServer: { contentBase: ‘./dist‘, hot: true, stats: ‘errors-only‘, }, };
state的取值有:
我们希望是在发生错误的时候输出,当state为error-only时,如果没有错误,没有任何输出,不太友好。
借助插件:friendly-errors-webpack-plugin。此时将state设置成errors-only
npm i friendly-errors-webpack-plugin const FriendlyErrorsWebpackPlugin = require(‘friendly-errors-webpack-plugin‘); module.exports = { plugins: [ new FriendlyErrorsWebpackPlugin(), ], };
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1jot771valo8l
标签:plugin sse nbsp ons top doctype loader text webpack
原文地址:https://www.cnblogs.com/V587Chinese/p/11571515.html