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