webpack实践指南

来源:互联网 发布:常见协议的端口号 编辑:程序博客网 时间:2024/05/16 10:34

github原文地址

why webpack

因为React和Redux开发课程中都要到了webpack构建.:cry:
* 将多个js文件 Bundle 成单一文件
* 在前端程代码中使用 npm packages
* 可以编写 JavaScript ES6 或 ES7(需 babel 來转译)
* Minify 压缩或优化代码
* 将 LESS 或 SCSS 转换成 CSS
* 支持 HMR(Hot Module Replacement)热加载
* 支持将任意类型文件加入到 JavaScript 中
* 其他更多…

Official Dependency Tree

webpack教程

一、环境配置

step0: 必须有node环境

本机必须先安装node环境,可命令行键入:node -v //查看是否安装&node版本信息

step1:创建react项目并初始化npm管理包(package.json)

  • mkdir 01basicDemos 创建项目目录
  • npm init –yes 初始化npm管理包, --yes是默认确认了所有package包信息

step2: 添加依赖和插件

//1、本地webpack构建和webpack构建服务端npm install --save webpack webpack-dev-server//2、react核心库npm install --save react react-dom//3、babel转译用es6编写的Reactnpm install --save-dev babel-core babel-loader babel-preset-react babel-preset-es2015//4、转译css样式npm install --save-dev style-loader css-loader//5、转译sass(SASS-loader)npm install --save-dev sass-loader node-sass//6、单独打包 CSSnpm install --save-dev extract-text-webpack-plugin//7、转译image图片npm install --save-dev url-loader//8、转译Json格式数据npm install --save-dev json-loader//9、指定网页的模板,并将转译后输出的`xxx.js`插入`inject`到`index.html`中的插件npm install html-webpack-plugin --save-dev

step3、npm script构建脚本

"scripts": {  "dev": "webpack-dev-server --progress --config webpack.config.dev.js",  "prod": "webpack -p --progress --config webpack.config.prod.js"}

使用构建命令

npm run dev   //构建开发环境包npm run prod  //构建生产环境包

二、webpack教程介绍

包括dev开发环境构建的webpack.config.dev.jsprod生产环境构建的webpack.config.prod.js

section1、转译ES6编写的React(Babel-loader)


  • 1、webpack.config.js中转译配置,

test: /\.js[x]?$/匹配正则, x可省, 即配置jsx/js为后缀的文件

loaders: [  {test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader'}]
  • 2、转译ReactES6语法,项目目录下新建babel转译配置文件.babelrc
{  "presets": ["react", "es2015"]}

或者不需要.babelrc,只需要在webpack.config.js中转译配置如下:

query: The query setting can be used to pass Additional options to the loader.

loaders: [  {test: /\.js[x]?$/,exclude: /node_modules/,loader: 'babel',    query: {presets: ['es2015', 'react']}  }]

section2、多入口文件(Multiple entry files)

webpack.config.js中多入口配置

module.exports = {  entry: {    bundle1: './index.jsx',    bundle2: './testMultiEntry.js'  },  output: {    filename: '[name].js'  }};

section3、转译CSS样式文件(CSS-loader)


  • CSS-loader读取Css文件
  • Style-loader将样式标签插入Html网页中

!来链式调用多个loader, 执行顺序由右到左, 即先执行css-loader再到style-loader
index.jsx

import IndexCss from './styles/index.css';
index.css
body {  background-color: rgb(200, 56, 97);}
webpack.config.js
loader: [ { test: /\.css$/, loader: 'style-loader!css-loader' } ]

section4、转译sass(SASS-loader)

index.jsx

import BgCss from './styles/bg.scss';
bg.scss
$bg-color: #ddd;body {  background: {    color: $bg-color  };}
webpack.config.js
{ test: /\.scss$/, loaders: 'style-loader!css-loader!sass-loader' }

section5、Css模块化(CSS Module)

css-loader?modules让CSS模块化

即CSS文件默认是本地作用域,当然可以用:global(...)来套成全局.

app.css

.h1 {  color:red;}:global(.h2) {  color: blue;}
App.jsx
import StyleCss from './../styles/app.css';<h1 className={StyleCss.h1}>Hello World</h1><h2 className="h2">Hello Webpack</h2>
webpack.config.js
{ test: /\.css$/, loader: 'style-loader!css-loader?modules' }

section6、单独打包 CSS

把 CSS 从 js 文件当中独立出来.
webpack.config.prod.js

var ExtractTextPlugin = require('extract-text-webpack-plugin');plugins: [ new ExtractTextPlugin("style.css") ]loaders: [ { test: /\.(css|scss)$/,    loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules!sass-loader') },]plugins: [ new ExtractTextPlugin("[name].css") ]

section7、转译图片(Image loader)

App.jsx

import SmallImgSrc from './../../public/small.png';import BigImgSrc from './../../public/big.png';//指定src<img src={SmallImgSrc} /><img src={BigImgSrc} />
webpack.config.js
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }

?传参设置限制limit字节,当图片小于8192字节时,图片会转成Data URL;否则将转成正常的URL格式.

服务器加载后,可以看到`small.png` 和 `big.png`被转成如下:
<img src="data:image/png;base64,iVBOR...uQmCC"><img src="4853ca667a2b8b8844eb2693ac1b2578.png">

section8、转译json格式数据(Json loader)

testMultiEntry.js

import ContactsData from './../../public/contacts.json'; //获取json数据//打印出json格式中数据console.log(ContactsData.datas);
webpack.config.js
{ test: /\.json$/, loader: 'json-loader' }

section9、网页模板插件html-webpack-plugin

指定网页的模板,并将转译后输出的xxx.js插入inject到模板网页中的插件.

不设置fileName默认输出和template同名,不设置inject默认插入body.

webpack.config.js

var HtmlWebpackPlugin = require('html-webpack-plugin')var htmlWebpackPluginConfig = new HtmlWebpackPlugin({    template: __dirname + '/src/index.html',    filename: 'index.html',    inject: 'body'});plugins: [htmlWebpackPluginConfig]

section10、压缩js插件(UglifyJs Plugin)

webpack.config.prod.js

var webpack = require('webpack');var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;plugins: [  new uglifyJsPlugin({ compress: { warnings: false }  }),  new webpack.optimize.OccurrenceOrderPlugin()]
  • webpack.optimize.UglifyJsPlugin - Minify 压缩代码,并显示警告信息
  • 也可以加入 OccurrenceOrderPlugin。

通过发生的次数 module 和 chunk 的 id。一些常用的 Id 取得较低(短)的 id。这使得 id 可以预测,减小大小.

section11、抽离公共js部分(Common chunk)

webpack.config.js

// 抽离公共js部分var webpack = require('webpack');var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');plugins: [ commonsPlugin ]

section12、热加载两种方式(Hot Module Replacement)

(1) 设置devServer

devServer: {    contentBase: "./dist",    inline: true,    port: 8888,       colors: true,    historyApiFallback: true}
  • contentBase: 默认以根目录挂到服务端
  • port: 默认端口8080
  • inline: 为ture,修改代码后会自动刷新浏览器显示最新代码
  • historyApiFallback: 使用html5的history的API,不匹配的路由都会打开/

(2) 添加HotModuleReplacementPlugin插件

  • 添加 new webpack.HotModuleReplacementPlugin()plugins 插件区域
  • 添加 webpack/hot/dev-serverwebpack-dev-server/client?http://localhost:8080entry 入口区域

webpack.config.dev.js

var webpack = require('webpack');module.exports = {  entry: [    'webpack/hot/dev-server',    'webpack-dev-server/client?http://localhost:8080',    './index.js'  ],  plugins: [    new webpack.HotModuleReplacementPlugin()  ]};

section13、省略文件后缀名

如:可以 import ‘./myJSFile’ 而不需要指定文件后缀 import ‘./myJSFile.jsx’

resolve: { extensions: ['.js', '.jsx']}

只是赶脚有后缀可以直接看清楚是什么类型文件,所以demos中webpack.config.js并不添加使用resolve.

section14、环境标识符(Environment flags)

testMultiEntry.js

// 测试开发环境if (__DEV__) {  console.log('这是在开发环境下');}

webpack.config.dev.js

var devFlagPlugin = new webpack.DefinePlugin({  __DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))});plugins: [devFlagPlugin]

package.json

env DEBUG=true webpack-dev-server

参考资源

  • 官方文档
  • 中文指南
  • webpack-demos 作者: ruanyf
  • Webpack for React 书: pro react书
  • webpack使用优化 from: AlloyTeam
  • webpack收藏系列 from: github
0 0