动手搭建react开发环境一
2019.07.11
hzzly
前言:接触webpack从在学校的那会起,也一直在使用它,用的都是别人封装好的,偶尔去修改一点点配置,也没有真正自己从零开始配置一个脚手架,接下来几篇将记录我对webpack以及开发中提升效率的配置,其中遇到的一些坑也会提示出来。
版本
本篇主要使用webpack搭建基础的React环境
快速浏览:
webpack核心概念
- entry: 入口起点
- output: 输出
- module: 模块,webpack中一切皆是模块
- loader: 转换工具,webpack 只能理解 JavaScript 和 JSON 文件。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中
- plugin: 扩展插件,loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务,在webpack构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要做的事情,比如:打包优化,资源管理,注入环境变量等等
- mode: webpac的打包环境[development, production]
- chunk: 代码库,一个chunk由十多个模块组合而成,用于代码合并与分割
基础配置
1、初始化项目
1 2 3 4
| mkdir webpack-template cd webpack-template mkdir src public build dist npm init -y
|
2、安装webpack
1 2 3
| yarn add webpack webpack-cli -D cd build touch webpack.config.js
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
const path = require('path'); module.exports = { mode: "development", entry: ["./src/index.js"], output: { path: path.resolve(__dirname, "../dist"), filename: "bundle.js" }, module:{}, plugins:[] }
|
package.json更改
1 2 3
| "scripts": { "start": "webpack --config ./build/webpack.config.js" },
|
3、HtmlWebpackPlugin
将打包的js自动插入到 index.html 里面去。
1 2 3
| yarn add html-webpack-plugin -D cd public touch index.html
|
1 2 3 4 5 6 7 8 9 10 11 12
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Webpack Template</title> </head> <body> <div id="root"></div> </body> </html>
|
1 2 3 4 5 6 7 8 9 10 11
| const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { plugins:[ new HtmlWebpackPlugin({ filename: 'index.html', template: path.join(__dirname, '../public/index.html'), }), ] }
|
4、配置转义ES6/ES7/JSX
1 2 3 4 5 6 7 8
| // @babel/polyfill: 模拟一个es6+的环境,提供es6方法和函数的垫片 // core-js@2:@babel/preset-env实现按需引入polyfill时,声明core-js版本 yarn add @babel/polyfill core-js@2 // babel-loader和@babel/core是核心模块 // @babel/preset-env是一个智能预设,允许您使用最新的JavaScript // @babel/preset-react 转换JSX yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react @babel/plugin-proposal-class-properties -D
|
1 2 3 4 5 6 7 8 9 10 11 12
| module.exports = { module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: 'babel-loader', } ], }, }
|
新建.babelrc文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { "presets": [ [ "@babel/preset-env", { "useBuiltIns": "usage", "corejs": 2 }, ], "@babel/preset-react" ], "plugins": [ "@babel/plugin-proposal-class-properties" ] }
|
🔥Tip1 问题:Support for the experimental syntax ‘classProperties’ isn’t currently enabled
yarn add @babel/plugin-proposal-class-properties 并在plugins中配置
🔥Tip2 提示:useBuiltIns 和 transform-runtime 不能同时使用,如果使用transform-runtime就不要配useBuiltInsor,一般独立的类库项目才用transform-runtime
5、配置转义Typescript
1
| yarn add typescript ts-loader -D
|
1 2 3 4 5 6 7 8 9 10 11 12
| module.exports = { module: { rules: [ { test: /\.tsx?$/, exclude: /node_modules/, loader: "ts-loader" } ], }, }
|
新建tsconfig.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| { "compilerOptions": { "baseUrl": ".", "rootDir": ".", "outDir": "dist", "module": "esnext", "target": "es6", "lib": ["dom", "es7"], "jsx": "preserve", "moduleResolution": "node", "sourceMap": true, "allowJs": true, "forceConsistentCasingInFileNames": true, "noImplicitReturns": true, "noImplicitThis": true, "noImplicitAny": true, "noUnusedLocals": true, "noUnusedParameters": true, "strictNullChecks": true, "importHelpers": true, "suppressImplicitAnyIndexErrors": true, "experimentalDecorators": true, "downlevelIteration": true, "allowSyntheticDefaultImports": true, "paths": { "@/*": ["src/*"] } }, "exclude": ["node_modules", "dist", "build", "mock"] }
|
6、CleanWebpackPlugin
清除 dist 目录下旧版本文件。
1
| yarn add clean-webpack-plugin -D
|
1 2 3 4 5 6 7 8 9
| const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { plugins:[ new CleanWebpackPlugin() ] }
|
7、source-map
可以帮助我们定位到错误信息位置的文件
1 2
| devtool: "cheap-module-eval-source-map", devtool: "cheap-module-source-map",
|
8、WebpackDevServer
webpack在本地为搭建了一个静态文件服务器,实时打包重加载修改的代码。
1
| yarn add webpack-dev-server -D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| module.exports = { devServer: { hot: true, contentBase: path.resolve(__dirname, "../dist"), host: "localhost", port: 8586, historyApiFallback: true, proxy: { } } }
|
修改package.json命令
1 2 3 4
| "scripts": { "start": "webpack-dev-server --config ./build/webpack.config.js", },
|
9、编译css和scss并使用css-modules
1
| yarn add css-loader style-loader sass-loader node-sass -D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| module.exports = { module: { rules: [ { test: /\.(sc|sa|c)ss$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: { localIdentName: '[local]_[hash:base64:5]', }, }, }, 'sass-loader', ], }, ], }, }
|
🔥Tip3 问题:当在 css-loader 配置上 sourceMap 时,配合热加载样式会闪屏
sourceMap: !isDev && true,
10、集成postcss
为css某些特性自动增加前缀,并做一些兼容处理。
1
| yarn add postcss-loader postcss-preset-env -D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| module.exports = { module: { rules: [ { test: /\.(sc|sa|c)ss$/, use: [ 'postcss-loader', 'sass-loader', ], }, ], }, }
|
新建postcss.config.js文件
1 2 3 4 5 6
| module.exports = { loader: 'postcss-loader', plugins: { 'postcss-preset-env': {}, } }
|
新建.browserlistrc文件
1 2 3 4
| 1% in CN android >= 4.4 ios >= 8 not ie <= 11
|
11、图片处理
1 2 3
| yarn add file-loader url-loader -D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| module.exports = { module: { rules: [ { test: /\.(png|jpg|jpeg|gif|svg)/, use: { loader: 'url-loader', options: { outputPath: 'images/', limit: 10 * 1024, }, }, }, ], }, }
|
12、字体文件处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| module.exports = { module: { rules: [ { test: /\.(eot|woff2?|ttf|svg)$/, use: [ { loader: 'url-loader', options: { name: '[name]-[hash:5].min.[ext]', limit: 5000, publicPath: 'fonts/', outputPath: 'fonts/', }, }, ], }, ], }, }
|
到这里,webpack的基本配置我们已经准备的差不多了,赶紧写点react来试试水。
测试React环境
1
| yarn add react react-dom react-router react-router-dom
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import React, { PureComponent } from 'react'; import ReactDOM from 'react-dom'; export default class App extends PureComponent { render() { return ( <div> hello word~ </div> ) } } ReactDOM.render( <App />, document.getElementById('root') );
|
执行 npm start
,如果页面上能正常显示 hello word~
那表示我们的webapck基础配置成功。
第一篇webpack基础配置到此结束了,下一篇对webpack进行优化配置。