webpack入门(2)

ps:每个案例都是基于前一个案例改造的

webpack入门(1) 戳这里

案例源码戳这里


十二、ProvidePlugin

自动加载模块

new webpack.ProvidePlugin()

上面的案例太复杂,下面再新建一个简单的项目来讲解


案例16 -- 全局引入jquery

新建一个项目,如下

[webpack]
|-- src
|-- index.html
|-- index.less
|-- index.js
|-- package.json
|-- webpack.config.js

webpack/package.json

{
"name": "webpack",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "webpack-dev-server --content-base build --inline --hot",
"build": "webpack -p",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"css-loader": "^0.28.7",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"html-webpack-plugin": "^2.30.1",
"jquery": "^3.2.1",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"style-loader": "^0.19.0",
"url-loader": "^0.6.2",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.9.5"
}
}

webpack/webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = {
entry: { // 入口文件地址
index: './src/index.js',
jquery: [ "jquery" ]
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract('css-loader')
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader')
},
{
test: /\.(png|jpg)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index', 'jquery'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'jquery' // 对应entry的key
}),
new webpack.ProvidePlugin({ // 全局引入jquery
$: 'jquery'
})
]
}

webpack/src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpackDemo</title>
</head>
<body> </body>
</html>

webpack/src/index.less

body {
background: lightpink;
}

webpack/src/index.js

import './index.less';
$('body').prepend('hi');

在webpack.config.js里设置了全局引入jquery,这里就不需要

import $ from 'jquery'

可以直接用 $

$ npm run start , 打开 http://localhost:8080/index.html , 效果如下


十三、iconfont

点击这里下载 案例17 使用的iconfont文件,以下简称“案例17压缩包”


案例17

新增文件 iconfont.less 和 iconfont.ttf(案例17压缩包里的iconfont.ttf),将index.less移动至css文件夹下,如下

[webpack]
|-- src
|-- images
|-- iconfont.ttf
|-- css
|-- iconfont.less
|-- index.less
|-- index.html
|-- index.js
|-- package.json
|-- webpack.config.js

webpack/src/css/iconfont.less

@font-face {
font-family: "iconfont";
src: url('../images/iconfont.ttf') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-love:before { content: "\e612"; }

webpack/src/css/index.less

@import './iconfont.less';
body {
background: lightpink;
.iconfont {
font-size: 50px;
}
}

webpack/src/index.js

import './css/index.less';
$('body').prepend('<i class="iconfont icon-love"></i>');

webpack/webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = {
entry: { // 入口文件地址
index: './src/index.js',
jquery: [ "jquery" ]
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract('css-loader')
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader')
},
{
test: /\.(png|jpg|ttf)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index', 'jquery'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'jquery' // 对应entry的key
}),
new webpack.ProvidePlugin({ // 全局引入jquery
$: 'jquery'
})
]
}

本案例只引入了ttf,其他可以类似添加

{
test: /\.(png|jpg|ttf|svg|eot|woff)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}

$ npm run start , 打开 http://localhost:8080/index.html ,效果如下

$ npm run build , iconfont.ttf文件小会转为base64直接打包到index.css里,如果文件比较大,则会单独打包到webpack/build/images/iconfont.ttf


十四、externals

externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。

比如 jquery 希望通过 cdn 的方式引入,代码里依旧用 import 的方式来使用,但是又不希望被打包。


案例18

webpack/src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpackDemo</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
</html>

webpack/src/index.js

import $ from 'jquery';
import './css/index.less';
$('body').prepend('<i class="iconfont icon-love"></i>');

webpack/webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = {
entry: { // 入口文件地址
index: './src/index.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
externals: {
jquery: 'jQuery' // jquery不被webpack编译到文件中
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract('css-loader')
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader')
},
{
test: /\.(png|jpg|ttf)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
})
]
}

运行 $ npm run build , 生成文件目录如下

[webpack]
|-- build
|-- index.css
|-- index.html
|-- index.js

十五、react

安装依赖

$ npm i babel-preset-react react react-dom --save-dev


案例19

webpack/src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpackDemo</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

webpack/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './css/index.less'; class Demo extends React.Component {
render() {
return (
<i className="iconfont icon-love" />
);
}
} ReactDOM.render(
<Demo />,
document.getElementById('root')
);

webpack/webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = {
entry: { // 入口文件地址
index: './src/index.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.(js|jsx)$/, // js-loader
loader: 'babel-loader?presets[]=es2015&presets[]=react'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract('css-loader')
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader')
},
{
test: /\.(png|jpg|ttf)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
})
]
}

需要babel-preset-react插件来编译React

运行 $ npm run start , 打开 http://localhost:8080/ ,能看到效果

运行 $ npm run build ,打包文件目录如下:

[webpack]
|-- build
|-- index.css
|-- index.html
|-- index.js

react被打包到webpack/build/index.js里去了


案例20 -- react 通过 cdn 的方式引入

webpack/src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpackDemo</title>
</head>
<body>
<div id="root"></div>
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
</body>
</html>

webpack/webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = {
entry: { // 入口文件地址
index: './src/index.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
externals: {
'react': 'React',
'react-dom': 'ReactDOM'
},
module: {
loaders: [
{
test: /\.(js|jsx)$/, // js-loader
loader: 'babel-loader?presets[]=es2015&presets[]=react'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract('css-loader')
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader')
},
{
test: /\.(png|jpg|ttf)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
})
]
}

这样 react 就不会被打包入 webpack/build/index.js


十六、devServer

  • hot : boolean , 启用 webpack 的模块热替换特性
  • inline : boolean , 内联模式(默认) , false 时为 iframe 模式
  • contentBase : boolean|string|array , 设定webpack-dev-server的director根目录。如果不进行设定的话,默认是在当前目录下。
  • compress : boolean , 一切服务都启用 gzip 压缩
  • port : number , 指定要监听请求的端口号
  • host : string , 指定使用一个 host
  • proxy : object , webpack 代理
  • filename : string , 可以只在某个文件时被请求时编译
  • headers : object , 在所有请求中添加首部内容

更多参数戳这里


案例21

新建一个项目如下

[webpack]
|-- package.json
|-- webpack.config.js
|-- src
|-- index.html
|-- index.js
|-- images
|-- SpongeBob.jpg
|-- css
|-- index.less

本案例用到的图片 SpongeBob.jpg 戳这里

webpack/package.json

{
"name": "webpack",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "webpack-dev-server",
"build": "webpack -p"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.7",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"html-webpack-plugin": "^2.30.1",
"jquery": "^3.2.1",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"style-loader": "^0.19.0",
"url-loader": "^0.6.2",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.9.5"
}
}

webpack/webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = {
entry: { // 入口文件地址
index: './src/index.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
externals: {
'jquery': 'jQuery', // 不打包jquery
},
module: {
loaders: [
{
test: /\.(js|jsx)$/, // js-loader
loader: 'babel-loader?presets[]=es2015&presets[]=react'
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader')
},
{
test: /\.(png|jpg|ttf)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
devServer: {
contentBase: './build',
inline: true,
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
})
]
}

webpack/src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpackDemo</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
</html>

webpack/src/css/index.less

body {
background: url(../images/SpongeBob.jpg) no-repeat;
color: blue;
}

webpack/src/index.js

import './css/index.less';

$('body').prepend('hi')

package.json 对比

// 案例16
"scripts": {
"start": "webpack-dev-server --content-base build --inline --hot",
}
// 案例21
"scripts": {
"start": "webpack-dev-server",
}

案例21 中 webpack-dev-server 后的参数,改为在 webapck.config.js 中设置

{
devServer: {
contentBase: './build',
inline: true,
hot: true
},
plugins: [ new webpack.HotModuleReplacementPlugin() ]
}

$ npm run start , 打开 http://localhost:8080/ , 效果如下


十七、本地 mock 模拟后端数据

{
devServer: {
before: (app) =>{
app.get('/init.json', function(req, res) {
res.json({ title: 'webpack' });
});
}
}
}

案例22

webpack/webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = {
entry: { // 入口文件地址
index: './src/index.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
externals: {
'jquery': 'jQuery', // 不打包jquery
},
module: {
loaders: [
{
test: /\.(js|jsx)$/, // js-loader
loader: 'babel-loader?presets[]=es2015&presets[]=react'
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader')
},
{
test: /\.(png|jpg|ttf)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
devServer: {
contentBase: './build',
inline: true,
hot: true,
before: (app) =>{
app.get('/init.json', function(req, res) {
res.json({ title: 'webpack' });
});
}
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
})
]
}

webpack/src/index.js

import './css/index.less';

$.ajax({
url: '/init.json',
data: {},
type: 'GET',
success: (d = {}) => {
$('body').prepend(d.title);
},
error: () => {
$('body').prepend('ajax error');
}
});

$ npm run start , 打开 http://localhost:8080/index.html , 效果如下

如果是 post 请求,webpack.config.js 如下

{
devServer: {
before: (app) =>{
app.post('/init.json', function(req, res) {
res.json({ title: 'webpack' });
});
}
}
}

当然,也可以不在 res.json() 中直接写 mock 数据,可以在外面命名变量,或者从其他文件引入

var mock_init = require('xxxxx');
var mock_user = { title: 'webpack' };
module.exports = {
devServer: {
before: (app) =>{
app.post('/init.json', function(req, res) {
res.json(mock_init);
});
app.post('/user.json', function(req, res) {
res.json(mock_user);
});
}
}
}

十八、环境变量

DefinePlugin 可以把命令行的环境变量带到浏览器端。

new webpack.DefinePlugin()

详解戳这里


案例23

环境变量在很多情况都会使用,这里举一个例子,比如我们本地 mock 数据时,请求都是 "localhost:8080" 开头的,但是到线上了则是 "http://a.com" 和 "http://b.com" , 这个时候就可以使用 DefinePlugin 来解决

webpack/package.json

{
"name": "webpack",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "NODE_ENV=mock webpack-dev-server",
"prod": "NODE_ENV=prod webpack-dev-server",
"build-start": "NODE_ENV=mock webpack -p",
"build-prod": "NODE_ENV=prod webpack -p"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.7",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"html-webpack-plugin": "^2.30.1",
"jquery": "^3.2.1",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"style-loader": "^0.19.0",
"url-loader": "^0.6.2",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.9.5"
}
}

"NODE_ENV=xxx" , 可以定义不同环境的 NODE_ENV

start 和 build-start , 是我们本地开发时使用 ; prod 和 build-prod , 是线上环境使用

webpack/webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); console.log('----------- NODE_ENV ----------- : ', process.env.NODE_ENV) module.exports = {
entry: { // 入口文件地址
index: './src/index.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
externals: {
'jquery': 'jQuery', // 不打包jquery
},
module: {
loaders: [
{
test: /\.(js|jsx)$/, // js-loader
loader: 'babel-loader?presets[]=es2015&presets[]=react'
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader')
},
{
test: /\.(png|jpg|ttf)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
devServer: {
contentBase: './build',
inline: true,
hot: true,
before: (app) =>{
app.get('/init.json', function(req, res) {
res.json({ title: 'webpack' });
});
}
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
})
]
}

通过 process.env.NODE_ENV 变量拿到值

$ npm run start , 效果如下

$ npm run prod , 效果如下

webpack/webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); const checkHost = {
"mock": {
"A_HOST": "http://localhost:8080",
"B_HOST": "http://localhost:8080",
},
"prod": {
"A_HOST": "http://a.com",
"B_HOST": "http://b.com",
}
} var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock'; var checkHostContent = checkHost[checkHostKey]; for (i in checkHostContent) {
checkHostContent[i] = JSON.stringify(checkHostContent[i]);
} module.exports = {
entry: { // 入口文件地址
index: './src/index.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
externals: {
'jquery': 'jQuery', // 不打包jquery
},
module: {
loaders: [
{
test: /\.(js|jsx)$/, // js-loader
loader: 'babel-loader?presets[]=es2015&presets[]=react'
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader')
},
{
test: /\.(png|jpg|ttf)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
devServer: {
contentBase: './build',
inline: true,
hot: true,
before: (app) =>{
app.get('/init.json', function(req, res) {
res.json({ title: 'webpack' });
});
}
},
plugins: [
new webpack.DefinePlugin(checkHostContent),
new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
})
]
}

分析如下

const checkHost = {
"mock": { // 本地 mock 数据使用
"A_HOST": "http://localhost:8080",
"B_HOST": "http://localhost:8080",
},
"prod": { // 线上环境使用
"A_HOST": "http://a.com",
"B_HOST": "http://b.com",
}
} // 检查 checkHost[process.env.NODE_ENV] 是否存在,不存在时,将rocess.env.NODE_ENV 设置为 mock
var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock'; // checkHostContent 相当于是 checkHost.mock 或 checkHost.prod
var checkHostContent = checkHost[checkHostKey]; // 如果 DefinePlugin 键值是一个字符串,它会被当作一个代码片段来使用,需要 JSON.stringify() 处理
for (i in checkHostContent) {
checkHostContent[i] = JSON.stringify(checkHostContent[i]);
} // 将处理好的 checkHostContent 放入
module.exports = {
plugins: [new webpack.DefinePlugin(checkHostContent)]
}

这一部分代码,将我们要用到的 A_HOST 和 B_HOST 都处理好,再放入new webpack.DefinePlugin(),拿 prod 举例,相当于处理成

module.exports = {
plugins: [new webpack.DefinePlugin({
A_HOST: JSON.stringify("http://a.com"),
B_HOST: JSON.stringify("http://b.com"),
})]
}

webpack/src/index.js

import './css/index.less';

console.log(A_HOST, B_HOST)

$.ajax({
url: `${A_HOST}/init.json`,
data: {},
type: 'GET',
success: (d = {}) => {
$('body').prepend(d.title);
},
error: () => {
$('body').prepend('ajax error');
}
});

$ npm run start , 效果如下

$ npm run prod , 效果如下

当然,也可以直接写两个 webpack.config.js 文件,这里就贴一下代码,不具体写案例了

// webpack.start.config.js
module.exports = {
plugins: [new webpack.DefinePlugin({
A_HOST: JSON.stringify("http://localhost:8080"),
B_HOST: JSON.stringify("http://localhost:8080"),
})]
} // webpack.prod.config.js
module.exports = {
plugins: [new webpack.DefinePlugin({
A_HOST: JSON.stringify("http://a.com"),
B_HOST: JSON.stringify("http://b.com"),
})]
} // package.json
{
"scripts": {
"start": "webpack-dev-server --config webpack.start.config.js",
"prod": "webpack-dev-server --config webpack.prod.config.js",
"build-start": "webpack -p --config webpack.start.config.js",
"build-prod": "webpack -p --config webpack.prod.config.js"
}
}

十九、server.js

详细介绍戳这里


案例24

新增 webpack/server.js , 目录如下

[webpack]
|-- server.js
|-- package.json
|-- webpack.config.js
|-- src
|-- index.html
|-- index.js
|-- images
|-- SpongeBob.jpg
|-- css
|-- index.less

webpack/webpack.config.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); const checkHost = {
"mock": { // 本地 mock 数据使用
"A_HOST": "http://localhost:8080",
"B_HOST": "http://localhost:8080",
},
"prod": { // 线上环境使用
"A_HOST": "http://a.com",
"B_HOST": "http://b.com",
}
} // 检查 process.env.NODE_ENV 是否和 checkHost 里的对应
var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock'; // checkHostContent 相当于是 checkHost.mock 或 checkHost.prod
var checkHostContent = checkHost[checkHostKey]; // 如果 DefinePlugin 键值是是一个字符串,它会被当作一个代码片段来使用,需要 JSON.stringify() 处理
for (i in checkHostContent) {
checkHostContent[i] = JSON.stringify(checkHostContent[i]);
} module.exports = {
entry: { // 入口文件地址
index: ['./src/index.js']
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
externals: {
'jquery': 'jQuery', // 不打包jquery
},
module: {
loaders: [
{
test: /\.(js|jsx)$/, // js-loader
loader: 'babel-loader?presets[]=es2015&presets[]=react'
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader')
},
{
test: /\.(png|jpg|ttf)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [
new webpack.DefinePlugin(checkHostContent), // 将处理好的 checkHostContent 放入
new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
})
]
}

将 devServer 删除 , entry.index 改为 array 写法

webpack/server.js

// 引入 webpack 和 webpack-dev-server
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server'); // 引入 webpack 的配置
var config = require('./webpack.config.js'); // 添加 webpack-dev-server 的客户端入口文件到 webpack 的配置中
// 通过 unshift 方法,将 webpack-dev-server/client?http://«path»:«port»/ 插入到 webpack-dev-server 配置的 entry.index 中
config.entry.index.unshift("webpack-dev-server/client?http://localhost:8080/"); // compiler = webpack({ webpack 的配置 })
var compiler = webpack(config); // server = new WebpackDevServer(compiler, { devServer 的配置 })
var server = new WebpackDevServer(compiler, {
contentBase: './build',
inline: true,
hot: true,
before: (app) =>{
app.get('/init.json', function(req, res) {
res.json({ title: 'webpack' });
});
}
}); server.listen(8080, "localhost", function() {});

webpack-dev-server 的配置里没有 inline : true 这个配置项, 因为 webpack-dev-server 无法访问 webpack 的配置。 因此,用户必须添加 webpack-dev-server 的客户端入口文件到 webpack 的配置中,有以下几种方式(上面案例只写了一种,其他大家可以自行尝试)

// server.js
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/"); // webpack.config.js
{
entry: {
index: [
'webpack-dev-server/client?http://localhost:8080/',
'./src/index.js'
]
}
}
// index.html
<script src="http://localhost:8080/webpack-dev-server.js"></script>

webpack/package.json

{
"name": "webpack",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "NODE_ENV=mock node server.js",
"prod": "NODE_ENV=prod node server.js",
"build-start": "NODE_ENV=mock webpack -p",
"build-prod": "NODE_ENV=prod webpack -p"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.7",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"html-webpack-plugin": "^2.30.1",
"jquery": "^3.2.1",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"style-loader": "^0.19.0",
"url-loader": "^0.6.2",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.9.5"
}
}

修改了 scripts.start 和 scripts.prod ,$ npm run start 和 $ npm run prod ,效果和 案例23 一样


二十、module.rules

下面介绍一下 loaders 的其他写法


案例25

webpack/server.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); const checkHost = {
"mock": { // 本地 mock 数据使用
"A_HOST": "http://localhost:8080",
"B_HOST": "http://localhost:8080",
},
"prod": { // 线上环境使用
"A_HOST": "http://a.com",
"B_HOST": "http://b.com",
}
} // 检查 process.env.NODE_ENV 是否和 checkHost 里的对应
var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock'; // checkHostContent 相当于是 checkHost.mock 或 checkHost.prod
var checkHostContent = checkHost[checkHostKey]; // 如果 DefinePlugin 键值是是一个字符串,它会被当作一个代码片段来使用,需要 JSON.stringify() 处理
for (i in checkHostContent) {
checkHostContent[i] = JSON.stringify(checkHostContent[i]);
} module.exports = {
entry: { // 入口文件地址
index: ['./src/index.js']
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
externals: {
'jquery': 'jQuery', // 不打包jquery
},
module: {
rules: [ // loaders
{
test: /\.(js|jsx)$/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', 'react']
}
}
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
use: [{
loader: "css-loader"
}, {
loader: "less-loader"
}]
})
},
{
test: /\.(png|jpg|ttf)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
name: 'images/[hash:8].[name].[ext]'
}
}
]
}
]
},
plugins: [
new webpack.DefinePlugin(checkHostContent), // 将处理好的 checkHostContent 放入
new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({ // 单独打包css
filename: '[name].css'
})
]
}

对比分析如下

{
module: {
// module.loaders 改为 module.rules
rules: [
// {
// test: /\.(js|jsx)$/, // js-loader
// loader: 'babel-loader?presets[]=es2015&presets[]=react'
// }
{
test: /\.(js|jsx)$/,
use: {
loader: 'babel-loader',
options: { // ? 后的参数可以写在这里
presets: ['es2015', 'react']
}
}
},
// {
// test: /\.less/, // less-loader
// loaders: ExtractTextPlugin.extract('css-loader!less-loader')
// }
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
use: [{
loader: "css-loader"
}, {
loader: "less-loader"
}]
})
},
// {
// test: /\.(png|jpg|ttf)$/, // img-loader
// loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
// }
{
test: /\.(png|jpg|ttf)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
name: 'images/[hash:8].[name].[ext]'
}
}
]
}
]
}
}

webpack入门(2)的更多相关文章

  1. webpack入门教程之Hello webpack(一)

    webpack入门教程系列为官网Tutorials的个人译文,旨在给予想要学习webpack的小伙伴一个另外的途径.如有不当之处,请大家指出. 看完入门教程系列后,你将会学习到如下内容: 1.如何安装 ...

  2. webpack入门——webpack的安装与使用

    一.简介 1.什么是webpack webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来使用和处理. ...

  3. 一小时包教会 —— webpack 入门指南

    什么是 webpack? webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来使用和处理. 我们可以 ...

  4. Webpack 入门指南 - 3. Hello, Angular2!

    Webpack 入门指南 - 1.安装 Webpack 入门指南 - 2.模块 这一次,我们使用 Webpack 来打包 Angular 2 的应用. 与官方的 Hello, Angular 2 项目 ...

  5. Webpack 入门指南 - 2.模块

    这一次我们谈谈模块问题. 通常我们希望这个项目可以分为多个独立的模块,比如,上一次提高的 hello 函数,如果我们定义为一个模块,其它模块引用之后,直接调用就好了.在前端怎么使用模块呢?这可说来话长 ...

  6. Webpack 入门指南 - 1.安装

    Webpack 是目前流行的打包工具,如何安装它呢? 1. 安装 Node Js 首先,Webpack 是基于 NodeJs 的工具,你必须首先安装 NodeJs. NodeJs 仅仅只需要在你的系统 ...

  7. webpack入门和实战(一):webpack配置及技巧

    一.全面理解webpack 1.什么是 webpack? webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都 ...

  8. webpack入门--前端必备

    webpack入门--前端必备 什么是 webpack? webpack是一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来 ...

  9. webpack入门笔记

    此为第一篇主要是webpack入门笔记: http://if-true.com/2015/10/16/webpack-tutorial-translate.html

  10. webpack入门必知必会

    关于 微信公众号:前端呼啦圈(Love-FED) 我的博客:劳卜的博客 知乎专栏:前端呼啦圈 前言 这是我第一篇介绍webpack的文章,先从一个入门教程开始吧,后续会有更多相关webpack的文章推 ...

随机推荐

  1. iOS开发针对对Masonry下的FPS优化讨论

    今天博客的内容就系统的讨论一下Masonry对FSP的影响,以及如何更好的使用Masonry.如果你对iOS开发足够熟悉的话,那么对Masonry框架应该不陌生.简单的说,Masonry的诞生让Aut ...

  2. [转载] 谷歌技术"三宝"之MapReduce

    转载自http://blog.csdn.net/opennaive/article/details/7514146 江湖传说永流传:谷歌技术有"三宝",GFS.MapReduce和 ...

  3. IIS解决CPU和内存占用率过高的问题

    发现进程中的w3wp占用率过高. 经过查询,发现如下: w3wp.exe是在IIS(因特网信息服务器)与应用程序池相关联的一个进程,如果你有多个应用程序池,就会有对应的多个w3wp.exe的进程实例运 ...

  4. 脱掉Golang的第一层衣裳 golang入坑系列

    读前必读,博客园的文章并非最新,想看最新还是建议点击这里.博客园的文章是为了方便不能FQ的同学,同步而来的.不放在博客园,不是不支持国产,而是博客园的排版太难看了,太难看了,太难看了!而且还没有客户端 ...

  5. 使用swiper简单的h5下滑翻页效果,

    <!DOCTYPE html><html lang="en"><head>  <meta charset="utf-8" ...

  6. 发现大量的TIME_WAIT解决办法 -- 修改内核参数

    今天早上一上班,有同事就反映公司好几个网站都打不开,登陆数据库 服务器(windows),发现很卡,于是重启了下服务器,进入系统后,没过一会问题依旧,查看了下系统进程,发现mysql占用率达到99%, ...

  7. 在ERP中定义用户时报错:SqlDateTime 溢出。必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之间

    在ERP中定义用户时.   报错: SqlDateTime 溢出.必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之间. 原因分析: ①没有正确初 ...

  8. 使用asp.net mvc引擎开发插件系统

    一.前言 我心中的插件系统应该是像Nop那样(更牛逼的如Orchard,OSGI.NET),每个插件模块不只是一堆实现了某个业务接口的dll,然后采用反射或IOC技术来调用,而是一个完整的mvc小应用 ...

  9. 万能动态库调用工具IDMA(InvokeDllMethodsAdvance)

    万能动态库调用工具IDMA 开发者:马兆瑞     QQ/微信:624762543 百度云下载链接:https://pan.baidu.com/s/1skW5W4H CSDN下载链接:http://d ...

  10. SQL图像查看器 —— SQL Image Viewer

    有时候往数据库里面存储了一些图片,但是如果不写读取程序的话,就不知道存储的对不对. 或者查看SQL数据库里面二进制看不懂,这个看图片很直观的. 就需要SQL Image Viewer这么一个