mkdir react-webpack-demo cd react-webpack-demo mkdir src mkdir dist npm init -y
安装webpack,并新建webpack.js文件,并初始化文件javascript
yarn add webpack webpack-cli webpack-dev-server -D mkdir config touch config/webpack.common.js
module.exports = { entry: ['./src/index.js'],//入口 output: { //出口 path: paths.appBuild }, module: {}, //配置 loader plugins: [], //插件 };
yarn add react react-dom
@babel/polyfill
1.babel 默认只转换 js 语法,而不转换新的 API,好比 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(好比 Object.assign)都不会转码。
2.babel-polyfill 会污染全局变量,给不少类的原型链上都做了修改,若是咱们开发的也是一个类库供 其余开发者使用,这种状况就会变得很是不可控。
3.类库开发,一般咱们会倾向于使用 babel-plugin-transform-runtime
4.@babel/preset-env 获取您指定的任何目标环境,,按需转码,引入相应的插件,默认使用browserslistcss
@babel/core-babel 核心模块 @babel/preset-env 编译ES6等 @babel/preset-react 转换JSX @babel/preset-react 转换JSX @babel/plugin-transform-runtime 避免 polyfill 污染全局变量,减少打包体积 @babel/polyfill ES6 内置方法和函数转化垫片
配置html
{ test: /\.(js|jsx)$/, include: paths.appSrc, use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-react'], plugins: [ // 按需加载lodash 'lodash', // babel-plugin-import // true是less, 能够写'css' 若是不用less ['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'less' }], [ '@babel/plugin-transform-runtime', { absoluteRuntime: false, corejs: false, helpers: false, regenerator: true, // generator不会污染全局的 useESModules: false, // 转换将使用没法运行的帮助程序 }, ], // '@babel/plugin-syntax-dynamic-import' ], cacheDirectory: true, cacheCompression: isEnvProduction, compact: isEnvProduction, }, }, ], }
Polyfill是一个js库,主要抚平不一样浏览器之间对js实现的差别。根据浏览器不一样的UA按需加载polyfill,国内浏览器支持很差。
<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfi...;></script>java
能够经过匹配文件是否带module分别配置是否要开始modulesnode
const cssRegex = /\.css$/; const cssModuleRegex = /\.module\.css$/;
module配置react
modules: { mode: 'local', localIdentName: '[local]--[hash:base64:5]', context: resolve(__dirname, 'src'), hashPrefix: 'my-less-hash', },
devServer: { hot: true, contentBase: paths.appBuild, host: "0.0.0.0", // 可使用手机访问 port: 8080, historyApiFallback: true, // 该选项的做用全部的404都链接到index.html compress: true, inline: true, }
resolve: { // 引入模块的时候,能够不用扩展名 extensions: ['.js', '.json', '.jsx'], // 别名 alias: { '@assets': resolve(__dirname, '../src/assets'), '@components': resolve(__dirname, '../src/components'), '@pages': resolve(__dirname, '../src/pages'), }, // 添加一个目录到模块搜索目录 modules: [resolve(__dirname, '../src'), 'node_modules'], },
css是直接打包进js里面的. 单独生成css,css能够和js并行下载,提升页面加载效率,
loader和plugins 都要配置webpack
output和new MiniCssExtractPlugin() 时,配置 filename: 'static/css/[name].[contenthash:8].css',web
optimizationnpm
optimization: { minimize: isEnvProduction, // 找出模块的顺序,最小的初始包,product 默认开启 occurrenceOrder: true, // runtimeChunk:会为每一个仅含有 runtime 的入口起点添加一个额外 chunk; // 值 "single" 会建立一个在全部生成 chunk 之间共享的运行时文件。此设置是以下设置的别名: runtimeChunk: { name: 'manifest' }, // usedExports 不导出未使用的代码 usedExports: true, concatenateModules: true, splitChunks: { // chunks: 'async', // 必须三选一: "initial" | "all"(推荐) | "async" (默认就是async) minSize: 30000, // 最小尺寸,默认值是30kb minChunks: 1, // 最小 chunk ,默认1 maxAsyncRequests: 5, // 最大异步请求数, 默认5 maxInitialRequests: 3, // 最大初始化请求数,默认3 automaticNameDelimiter: '-', // 打包分隔符 name: true, // 打包后的名称,此选项可接收 function //设置缓存组,用来抽取知足不一样规则的chunk cacheGroups: { // 这里开始设置缓存的 chunks vendor: { // key 为entry中定义的 入口名称 test: /[\\/]node_modules[\\/]/, // 正则规则验证,若是符合就提取 chunk chunks: 'initial', name: 'vendor', // 要缓存的 分隔出来的 chunk 名称 priority: 10, enforce: true, }, lazy: { test: ({ resource }) => { return /antd/.test(resource); }, chunks: 'async', name: 'lazy', priority: 10, enforce: true, }, commons: { chunks: 'all', test: ({ resource }) => { return /[\\/]node_modules[\\/]/.test(resource) && !shouldExcludeFromCommon.test(resource); }, name: 'common', minChunks: 2, maxInitialRequests: 5, minSize: 0, priority: 20, }, }, }, },
webpack4只要在生产模式下, 代码就会自动压缩json
new webpack.ProvidePlugin({ fetch: 'imports-loader?this=>global!exports-loader?global.fetch!whatwg-fetch', }),
DefinePlugin 容许建立一个在编译时能够配置的全局常量,这些值会被内联进那些容许传一个代码压缩参数的代码中,从而减小冗余的条件判断
new webpack.DefinePlugin({ PRODUCTION: JSON.stringify(true), VERSION: JSON.stringify("5fa3b9"), BROWSER_SUPPORTS_HTML5: true, TWO: "1+1", "typeof window": JSON.stringify("object") })
npm i glob-all purify-css purifycss-webpack --save-dev const PurifyCSS = require('purifycss-webpack') const glob = require('glob-all') plugins:[ // 清除无用 css new PurifyCSS({ paths: glob.sync([ // 要作 CSS Tree Shaking 的路径文件 path.resolve(__dirname, './src/*.html'), // 请注意,咱们一样须要对 html 文件进行 tree shaking path.resolve(__dirname, './src/*.js') ]) }) ]
清除到代码中无用的js代码,只支持import方式引入,不支持commonjs的方式引入
只要mode是production就会生效,develpoment的tree shaking是不生效的,由于webpack为了方便你的调试
optimization: {
usedExports:true,
}
缓存一次后 服务器挂了 还能够用
// // 预缓存
new GenerateSW({
clientsClaim: true, skipWaiting: true, importWorkboxFrom: 'local', include: [/\.js$/, /\.css$/, /\.html$/, /\.jpg/, /\.jpeg/, /\.svg/, /\.webp/, /\.png/],
}),
提取公共配置
module.exports = merge(common, webpackConfig);
MacBook Pro 2017上测试了几把 ,并无提高速度,反而慢了,后续再看。
resolve: {
alias: { '@ant-design/icons/lib/dist$': resolve(__dirname, '../src/assets/icons.js') },
}
并在icons.js 配置
若是是less 会报错:须要在less-loader option 里面添加javascriptEnabled: true,
若是添加自定义主题: 添加 modifyVars:
{
'primary-color': '#1DA57A', 'link-color': '#1DA57A', 'border-radius-base': '2px',
},
在index.html文件引入
module: { rules: [ { test: /\.css$/i, loader: 'css-loader', options: { modules: { mode: 'local', localIdentName: '[path][name]__[local]--[hash:base64:5]', context: path.resolve(__dirname, 'src'), hashPrefix: 'my-custom-hash', }, }, }, ], },
使用terser-webpack-plugin