前言
作者刘俊余,擅长前端开发(Html5,ReactNative,Js框架)
最近在折腾React+Mobx+Antd脚手架(React-scaffold),欢迎大家Star
这篇文章主要给大家讲解一下如何修改CRA项目的Webpack
前置条件(precondition)
-
Creating a New Application
-
安装yarn
npm install yarn -g
- 安装依赖
yarn install
- 显示webpack配置
npm run eject
- 添加alias
可以根据项目自行配置
alias: {
'react-native': 'react-native-web',
'src':path.join(__dirname, '..', 'src'),
'language':path.join(__dirname, '..', 'src/language'),
'router':path.join(__dirname, '..', 'src/router'),
'Modebase':path.join(__dirname, '..', 'src/Modebase'),
'containers':path.join(__dirname, '..', 'src/containers')
}
- 添加cssnext(postcs)
一种可以让你使用CSS最新特性的插件。它通过将最新的CSS特性转变为现阶段浏览器所兼容的特性,这样你不用再等待浏览器对某一特定新特性的支持。
修改webpack.config.dev.js添加postcss插件
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-cssnext', {
browsers: ['last 2 version']
})
],
}
}
这样我们就可以使用.css文件使用类似css预处理的语法比如这样
image.pngwebPack按需加载
- 添加react-router4
使用react-router-dom,参考初探 React Router 4.0
yarn add react-router-dom
- 在react-router4中进行代码拆分
react-router升级到4后,便没有了getComponent这个参数。所以我们得换种方式,react-router4官方示例也提供了code splitting的方法,利用webpack结合bundle-loader,它是在require.ensure基础上封装的,更友好的实现异步加载过程。
添加Bundle.js组件
export default class Bundle extends Component {
constructor(props) {
super(props);
this.state = {
mod: null
};
}
load = props => {
this.setState({
mod: null
});
props.load(mod => {
this.setState({
mod: mod ? mod : null
});
});
}
componentWillMount() {
this.load(this.props);
}
render() {
return this.state.mod ? this.props.children(this.state.mod) : null
}
}
使用require.ensure()来进行模块的异步加载
<Bundle load={(cb) => {
require.ensure([], require => {
cb(require('containers/Buttons/containers').default);
},'Buttons');
}}>
{(Buttons) => <Buttons {...props}/>}
</Bundle>
-
效果展示
image.png
webPack提取公共模块
- 首先把入口处改写为下面这样,把公共的方法提取出来
entry: {
app:[
require.resolve('./polyfills'),
paths.appIndexJs,require.resolve('react-error-overlay'),
require.resolve('react-dev-utils/webpackHotDevClient')
],
vendor: ['react', 'react-dom', 'react-router','react-router-dom', 'mobx', 'mobx-react']
}
- 提取公共模块
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.[hash:8].js'
})
Webpack DLL 用法
Dll使用方法其实挺简单的。网上也有很多例子。
我遇到一些坑这里和大家说明一下
首先在主目录下面新建webpack.dll.dev.js
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: {
vendor: [path.join(__dirname, 'src', 'vendor.js')],
},
output: {
path: path.join(__dirname, 'dll'),
filename: '[name].js',
library: '[name]',
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, 'dll', '[name]-manifest.json'),
filename: '[name].js',
name: '[name]',
}),
]
};
这个Webpack文件主要的功能是在根目录生成dll文件夹。里面包含有vendor.js(index.html需要添加的js)和vendor-manifest.json (DllPlugin生成的json文件)
在主webpack文件里面通过DllReferencePlugin插件引用
然后再package.json里面添加
webpack --config webpack.dll.dev.js
然后在主webpack文件添加如下代码
const manifest = require('../dll/vendor-manifest.json');
plugins: [
new webpack.DllReferencePlugin({
manifest
})
]
下面就是dll比较坑的地方,如何在index.html中引入verdor.js呢。
首先我们思考直接在public底下的index.html中直接引用,这个dllplugin的包并不会被打进内存里,需要指定一个static目录
解决办法使用AddAssetHtmlPlugin
在htmlwebpack后插入一个AddAssetHtmlPlugin插件,用于将vendor插入打包后的页面
new AddAssetHtmlPlugin({
filepath: require.resolve('../dll/vendor.js'), includeSourcemap: false })
搞定!
效果展示
节省了近30S
使用UglifyJsPlugin压缩代码
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false,
}
})
- 效果展示
添加ANTD全局组件和css
修改webpack对于webpack还有什么想要了解的。欢迎大家在底下评论哦。。
本人长期维护的前端公众号欢迎大家关注
前端那些事
网友评论