webpack的原理:
主要分析你的项目结构,找到JavaScript模块以及其他一些浏览器不能直接运行的拓展语言(Scss、less、TypeScript),将其转换和打包为合适的格式供浏览器使用
1\进入一个空文件夹,终端输入 npm init, 初始化packge.json 项目的依赖管理和脚本任务.
2\npm install react react-dom react-redux react-router --save-dev 安装react的相关东西,一般安装在devDependencies
3\安装webpack 打包工具 npm install webpack --save-dev
4\安装webpack的一些插件
npm install -D file-loader # 文件加载模块,用于加载图片,字体等静态资源文件
npm install -D json-loader # 加载json文件模块
npm install -D css-loader style-loader postcss-loader autoprefixer less-loader extract-text-webpack-plugin # 加载样式文件,这里使用了less引擎
npm install -D html-webpack-plugin # 配置一个html的模板容器,用于装载编辑的js代码
但是假如出现401错误:401 Authorization Required: html-webpack-plugin@latest
npm config get registry查看npm源 npm config set registry xxxxxx 更换源
有可能是一些环境原因导致
一些常用的react插件:
- 支持ES6 还需要安装babel-preset-env
babel-plugin-import
它会在编译过程中将 import 的写法自动转换为按需引入的方式 import { Button, Cell } from ‘vant’;npm install -D babel-core@6.x babel-loader@7.x babel-preset-env babel-preset-react babel-preset-stage-0 babel-polyfill
安装babel
cross-env
跨平台地设置及使用环境变量clean-webpack-plugin
用于清空dist文件夹,方便重新打包extract-text-webpack-plugin
将css样式单独打包成样式文件html-webpack-plugin
html模板导入工具optimize-css-assets-webpack-plugin
@3.x css打包样式最小化,新版本5.x对应webpack@4.xadd-dom-event-listener
事件监听工具,对addEventListener进行封装,兼容attachEventautoprefixer
自动为css样式添加-webkit- -o-等支持axios
http请求工具moment
时间管理工具js-cookie
cookie管理工具
进行webpack.config.js的编写:
const NODE_ENV = process.env.NODE_ENV;//生产环境
const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');//用于清空dist文件夹,方便重新打包
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');//这个插件是把css从js中分离出来的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');//模板导入工具
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');//css打包样式最小化,性能优化一方面
//filename 配置提取出来的css名称
const PROJECT_LESS = new ExtractTextWebpackPlugin({ filename: 'css/[name].css', allChunks: true });
module.exports ={
devtool: 'source-map',//source-map 是为了解决开发代码与实际运行代码不一致时帮助我们debug到原始开发代码的技术
entry:{
vendor: ['react', 'react-dom', 'redux', 'react-redux',
'react-router', 'autoprefixer',
'add-dom-event-listener', 'axios'],
main:path.join(__dirname,'src/entry')//在 src/entry 目录下新建index.js,指定入口文件,程序从这里开始编译
},
output:{
path:path.resolve(__dirname,'dist'),//输出路径
publicPath:'/', //为编译文件的路径,一般在index.html引入外部文件时路径的前缀
sourceMapFilename: 'map/[name].map',//.map文件都放到map文件夹下
filename:'js/[name].js',//打包后的文件
},
resolve:{//不是必备的 配置引入文件不用带后缀和路径别名
extensions: ['.js', '.jsx', '.json'],// 配置在尝试引入文件没带尾缀过程中用到的后缀列表
modules: [//配置webpack去哪些目录下寻找第三方模块
path.join('node_modules')
],
alias: {//配置项通过别名来把原来导入路径映射成一个新的导入路径
'@': path.join(__dirname, 'src'),
'components': path.join(__dirname, 'src/components'),
'images': path.join(__dirname, 'src/images'),
'lib': path.join(__dirname, 'src/lib'),
'masters': path.join(__dirname, 'src/masters'),
'pages': path.join(__dirname, 'src/pages'),
'router': path.join(__dirname, 'src/router'),
'store': path.join(__dirname, 'src/store'),
'theme': path.join(__dirname, 'src/theme'),
'config': path.join(__dirname, 'config')
}
},
module:{//处理各种文件的loader
rules:[
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test:/\.js$/,
loader:'babel-loader',
exclude:/node_modules/
},
{
test: /\.(png|jpe?g|gif|svg)$/,// 匹配特定文件的正则表达式或正则表达式数组
exclude: /node_modules/,// 指定转译时忽略的文件夹
loader: 'file-loader', // 依赖的loader
options: {
limit: 512,
name: 'images/[name].[ext]'
}
},
{
test: /\.(woff|svg|ttf|eot)$/,
loader: 'file-loader',
query: {
name: 'fonts/[name].[ext]'
}
},
{
test: /\.json$/,
exclude: /node_modules/,
loader: 'json-loader'
},
{
test: /\.less$/,
exclude: /node_modules/,
loader: PROJECT_LESS.extract({
fallback: 'style-loader',
use: [// 应用于模块的 loader 使用列表
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')()
]
}
},
{
loader: 'less-loader'
}
]
})
}
]
},
plugins: [//webpack用到的插件
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(NODE_ENV)
}
}),
new CleanWebpackPlugin(),
new webpack.optimize.CommonsChunkPlugin({ // 公共代码提取
name: ['vendor', 'runtime'],
filename: 'js/[name].js',
minChunks: Infinity
}),
new HtmlWebpackPlugin({
title: 'lxReact',
template: path.join(__dirname, 'src/views/template.html'), // 模板文件,必须
filename: 'index.html',
//favicon: path.join(__dirname, 'src/views/favicon.ico'), // favicon文件,非必须
inject: true,
chunks: ['vendor','runtime','main'], // 需要引入的包
minify: NODE_ENV == 'production' ? {
removeComments: true,//清理html中的注释。默认为false
removeAttributeQuotes: true,// 去掉标签上属性的引号
collapseWhitespace: true//清理html中的空格、换行符。
} : false
}),
PROJECT_LESS,
].concat(NODE_ENV == 'production' ? [
/**
* 生产模式下的配置
*/
new webpack.optimize.UglifyJsPlugin({ // js代码压缩
compress: {
warnings: false
}
}),
new OptimizeCssAssetsWebpackPlugin({ // css代码压缩
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorPluginOptions: {
preset: ['default', { discardComments: { removeAll: true } }],
},
canPrint: true
})
] : [])
}
然后配置babel,根文件下创建.babelrc文件.
{//presets是转码规则,plugins是设置的babel的插件。
"presets": [
"env",
"react",
"stage-0"
],
"plugins": []
}
创建目录如下.
在 src/views 下新建 index.html,作为模板模板容器文件
<!DOCTYPE html>
<html>
<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><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="app"></div>
</body>
</html>
favicon 用于显示浏览器标签上的logo,不是必须的,如果不需要,请把htmlwebpackplugin里面的favicon配置给注释掉
接着编写入口文件
在 src/entry 目录新建 index.js。
这里一般就是挂在在app下的东西.
ps:注意,之前出过一些start报错的情况,注意看报错信息.某些东西没装全.
以上就是打包,现在配置启动服务和mock
启服务热更新的方式 :
1、安装webpack-dev-server (此配置的)轻量级的node.js express服务器
//webpack.config.js
module.exports = {
…
//配置热更新
devServer: {
clientLogLevel: ‘warning’,
//contentBase: path.join(__dirname, “…/src”), 配置DevServer HTTP服务器的文件根目录。默认情况下为当前执行目录,所以一般不必设置它,
historyApiFallback: true,// 404的页面会自动跳转到/页面
hot: true,//是否启用模块热替换功能,在不刷新整个页面的情况下通过用心模块替换老模块来实现实时预览
inline:true,//实时更新,通过代理客户端,false的话是通过刷新ifram
compress: false,//配置是否启用 gzip 压缩,默认false
host: ‘0.0.0.0’,//访问ip
port: 3000,//端口
open: true,//是否默认打开
overlay: true,//在浏览器上全屏显示编译的errors或warnings。默认是关闭的。只想显示错误就是true,若都要{warnings:true,errors:true}
publicPath: ‘/’,//打包的文件将被部署到该配置对应的path。
//proxy: config[system].proxy || {}, 启用代理。
/quiet: true, // 当启用该配置,除了初始化信息会被写到console中,其他任何信息都不会被写进去。errors和warnings也不会被写到console中。/
},
…
plugins:[
……
new webpack.HotModuleReplacementPlugin()
]
}
注意:npm install webpack-dev-server@2.9
在webpack-dev-server的3.0.0版本开始,只兼容webpack4及以上版本,不再兼容webpack3及一下版本了
入口文件index.js处设置路由
import React from 'react';
import { render } from 'react-dom';
import { Router , Route , hashHistory } from 'react-router';
import home from '../pages/home';
render((
<Router history={hashHistory}>
<Route path="/" component={home}/>
</Router>
), document.getElementById('app'))
链接到你想要去的文件,例如home.js
import React from 'react';
import { Router, Route, hashHistory } from 'react-router';
class App extends React.Component{
constructor(props){
super(props);
this.state={
}
}
render() {
return (
<div>
<input placeholder="@mxstbr" type="text" />
<div style={{color:'red'}}>i am first h1</div>
</div>
);
}
}
export default App
启动后,你就能在`http://localhost:3000/#/``看到当前的home界面
2、express+http
一般是配置app.js,bin/www ,config/index.js
后续补充…
mock的使用:
1\
"json-loader": "^0.5.7",
"json-server": "^0.14.0",
"mock": "json-server --port 8800 --middlewares mock/middlewares.js --routes mock/routes.json --watch mock/faker-data.js"
2"mockjs": “^1.0.1-beta3”,
import Mock from ‘mockjs’;
Mock.mock(//ivisual/web/board/person/ponitStatus.do/, ‘post’, () => {