接触webpack是好久之前的事情了,最近看了下webpack没想到都到4了。

webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).

会创建1个依赖关系图(dependency graph),包含所有依赖的模块,然后将模块打包成1个或多个bundle.

webpack4 仍然支持高度可配,但完全可以不用配置文件了(基于mode)。

安装

淘宝源:npm config set registry https://registry.npm.taobao.org

升级npm:npm i npm -g

安装webpack:npm i -D webpack webpack-cli webpack-dev-server

运行webpack:npx webpack(Node 8.2+ 版本提供的npx命令)

基本特性

核心配置:

  • 入口(entry):
  • 输出(output):
  • loader:
  • 插件(plugins):

Entry

入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。

可以通过在 webpack 配置中配置 entry 属性,来指定一个入口起点(或多个入口起点)。默认值为 ./src/index.js

webpack.config.js

module.exports = {
entry: {
main: './src/index.js'
},
};

Output

output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为./dist/[name].js

webpack.config.js

const path = require('path');

module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
}
};

Loader

loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。

loaders 有2个核心参数:

  1. test 属性,用于标识出需要转换的某个或某些文件。
  2. use 属性,表示进行转换时,应该使用哪个 loader。
const path = require('path');

const config = {
output: {
filename: 'bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
}; module.exports = config;

Plugins

插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件 const config = {
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
}; module.exports = config;

Mode

通过选择 development 或 production 之中的一个,来设置 mode 参数

webpack.config.js

module.exports = {
mode: 'production'
};

mode.js

// webpack.development.config.js
module.exports = {
+ mode: 'development'
- plugins: [
- new webpack.NamedModulesPlugin(),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
- ]
}
// webpack.production.config.js
module.exports = {
+ mode: 'production',
- plugins: [
- new UglifyJsPlugin(/* ... */),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
- new webpack.optimize.ModuleConcatenationPlugin(),
- new webpack.NoEmitOnErrorsPlugin()
- ]
}

常用插件

HtmlWebpackPlugin:

Options

const HtmlWebpackPlugin = require('html-webpack-plugin');

new HtmlWebpackPlugin({ template: 'src/index.html', minify: true, hash: true })

CleanWebpackPlugin:

const CleanWebpackPlugin = require('clean-webpack-plugin');

new CleanWebpackPlugin(['dist'])

MiniCssExtractPlugin(ExtractTextPlugin):

new MiniCssExtractPlugin({ filename: "[name].css",chunkFilename: "[id].css" })

module: {
rules: [{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
]}
]
}

SplitChunksPlugin:

module.exports = {
mode: 'development',
entry: {
main: './src/index.js',
vendors: 'lodash'
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "initial"
}
}
}
}
}

配置示例

package

package.json

{
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --open",
"build": "webpack --config webpack.prod.js"
},
"devDependencies": {
"babel-loader": "^7.1.4",
"babel-preset-react": "^6.24.1",
"babel-plugin-import": "^1.7.0",
"clean-webpack-plugin": "^0.1.19",
"css-loader": "^0.28.11",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.4.0",
"webpack": "^4.8.3",
"webpack-cli": "^2.1.3",
"webpack-dev-server": "^3.1.4"
},
"dependencies": {
"antd": "^3.5.2",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"express": "^4.16.3",
"lodash": "^4.17.10",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-loadable": "^5.4.0",
"react-redux": "^5.0.7",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"redux": "^4.0.0",
"redux-logger": "^3.0.6",
"redux-promise": "^0.6.0",
"redux-saga": "^0.16.0",
"redux-thunk": "^2.2.0"
}
}

开发环境

const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const path = require('path'); module.exports = {
mode: 'development',
entry: {
main: './src/index.js',
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
module: {
rules: [{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
]
}, {
test: /\.(js|jsx)$/,
loader: 'babel-loader',
options: {
presets: ['react'],
plugins: [
["import", { "libraryName": "antd", "style": "css" }]
]
},
exclude: /node_modules/
}]
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({ minify: true, hash: true }),
new MiniCssExtractPlugin({ filename: "[name].css", chunkFilename: "[id].css" })
],
optimization: {
splitChunks: {
cacheGroups: {
common: {
test: /[\\/]node_modules[\\/]/,
name: "common",
chunks: "initial",
enforce: true
},
}
}
}
};

生产环境

const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const path = require('path'); module.exports = {
mode: 'production',
entry: {
main: './src/index.js',
},
devtool: 'source-map',
devServer: {
contentBase: './dist',
host: '192.168.0.75'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
module: {
rules: [{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
]
}, {
test: /\.(js|jsx)$/,
loader: 'babel-loader',
options: {
presets: ['react'],
plugins: []
},
exclude: /node_modules/
}]
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({ template: 'src/index.html', minify: true, hash: true }),
new MiniCssExtractPlugin({ filename: "[name].css", chunkFilename: "[id].css" })
],
externals: {
lodash: '_',
react: 'React',
'react-dom': 'ReactDOM',
antd: 'antd'
},
optimization: {
splitChunks: {
cacheGroups: {
common: {
test: /[\\/]node_modules[\\/]/,
name: "common",
chunks: "initial",
enforce: true
},
}
}
}
};

React从入门到放弃之前奏(1):webpack4简介的更多相关文章

  1. React从入门到放弃之前奏(5):ReactRouter4

    概念 安装:npm i -S react-router react-router-dom GitHub:ReactTraining/react-router React Router中有三种类型的组件 ...

  2. React从入门到放弃之前奏(2):React简介

    本系列将尽可能使用ES6(ES2015)语法.所以均在上节webpack的基础上做开发. React是Facebook开发的一款JS库,因为基于Virtual DOM,所以响应速度快,以及支持跨平台. ...

  3. React从入门到放弃之前奏(3):Redux简介

    安装 npm i -S redux react-redux redux-devtools 概念 在redux中分为3个对象:Action.Reducer.Store Action 对行为(如用户行为) ...

  4. React从入门到放弃之前奏(4):Redux中间件

    redux 提供了类似后端 Express 的中间件概念. 最适合扩展的是redux中的 store.dispatch 方法,中间件实际就是通过 override redux的store.dispat ...

  5. 在 2016 年学 JavaScript 是一种什么样的体验?(React从入门到放弃)

    jquery 年代 vs 前端模块化 http://blog.csdn.net/offbye/article/details/52793921 ++ 嘿,我最近接到一个 Web 项目,不过老实说,我这 ...

  6. ubuntu-docker入门到放弃(七)Dockerfile简介

    一.dockerfile基本结构 最简单的理解就是dockerfile实际上是一些命令的堆叠,有点像最基础的shell脚本,没有if 没有for,就是串行的一堆命令. 一般而言,dockerfile分 ...

  7. D3.js从入门到“放弃”指南

    前言 近期略有点诸事不顺,趁略有闲余之时,玩起D3.js.之前实际项目中主要是用各种chart如hightchart.echarts等,这些图形库玩起来貌都是完美的,一切皆可配置,但几年前接触了D3之 ...

  8. 一天带你入门到放弃vue.js(一)

    写在前面的话! 每个新的框架入手都会进行一些列的扯犊子!这里不多说那么多!简简单单说一下vue吧! Vue.js是目前三大框架(angular,vue,react)之一,是渐进式js框架,据说是摒弃了 ...

  9. 小白学 Python 爬虫(28):自动化测试框架 Selenium 从入门到放弃(下)

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

随机推荐

  1. linux进程管理之进程创建

    所谓进程就是程序执行时的一个实例. 它是现代操作系统中一个很重要的抽象,我们从进程的生命周期:创建,执行,消亡来分析一下Linux上的进程管理实现. 一:前言 进程管理结构; 在内核中,每一个进程对应 ...

  2. Microsoft Dynamics CRM 2011 JS操作集锦

    1.Xrm.Page.context 用户ID:getUserId() 用户角色:getUserRoles() 用户语言:getUserLcid() 组织名称:getOrgUniqueName() 组 ...

  3. Learning ROS for Robotics Programming Second Edition学习笔记(三) 补充 hector_slam

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  4. TCP的核心系列 — SACK和DSACK的实现(二)

    和18版本相比,37版本的SACK和DSACK的实现做了很多改进,最明显的就是需要遍历的次数少了, 减少了CPU的消耗.37版的性能提升了,代码有大幅度的改动,逻辑也更加复杂了. 本文主要内容:37版 ...

  5. 修改Tomcat访问的端口号

    修改Tomcat端口号步骤: 1.找到Tomcat目录下的conf文件夹 2.进入conf文件夹里面找到server.xml文件 3.打开server.xml文件 4.在server.xml文件里面找 ...

  6. 【编程练习】快速select算法的实现

    代码来自: http://blog.csdn.net/v_JULY_v 算法思想: // Quick_select.cpp : 定义控制台应用程序的入口点. // #include "std ...

  7. myeclipse不编译

    错误: org.eclipse.core.internal.registry.configurationElementHandle cannot be cast to org.eclipse.jdt. ...

  8. JQuery常用功能的性能优化

    使用最佳选择器 通常比较常用的选择器有以下几个: 1.ID选择器 $("#id") 2.标签选择器 $("td") 3.类选择器 $(".target ...

  9. java死锁小例子

    package cn.com.io.threadDemo.ThreadSyn; /** * 通过两个属性值创建死锁 * 本程序通过两个线程各自锁定一个属性值,这样两个线程都无法结束,造成死锁 * @a ...

  10. 多重影分身——C#中多线程的使用三(调用方法和传参)

    对Thread: 1.使用ThreadStart static void Main(string[] args) { Thread th1=new Thread(new ThreadStart(Say ...