Open Manjushaka opened 6 years ago
没有用到的js资源,webpack就不会打包进去。例如,项目中有一个extra.js文件,但是没有任何一个文件引用它,那么extra.js文件将不会被打包进去。如果仅仅是import,接下里的代码里面没有使用该import的文件,该被import的文件仍会被打包进去。
直接使用react-router,是无法刷新命中路由的,需要对服务器进行相应配置: 1) nodejs:
devServer: {
contentBase: './dist',
historyApiFallback: true,
hot: true,
port: 3013,
},
2)ngix
1.样式 css
npm install --save-dev style-loader css-loader
然后修改webpack.config.js文件:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
]
}
]
}
};
然后就可以在js文件里面直接import './style.css'了。 如果还想处理其他的less,sass文件等,就需要对应的loader。如postcss, less
2. 图片image
npm install --save-dev file-loader
然后修改webpack.config.js文件:
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
]
然后就可以:
import MyImage from './my-image.png'
.hello {
color: #f00;
background: url('./back.png');
}
<img src="./my-image.png" />
Check out the image-webpack-loader and url-loader for more on how you can enhance your image loading process.
3. 字体fonts 使用和图片相同的file-loader, 修改webpack.config.js文件:
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
然后在./src目录下加入需要的字体文化,
+ @font-face {
+ font-family: 'MyFont';
+ src: url('./my-font.woff2') format('woff2'),
+ url('./my-font.woff') format('woff');
+ font-weight: 600;
+ font-style: normal;
+ }
.hello {
color: red;
+ font-family: 'MyFont';
background: url('./icon.png');
}
4. 数据data JSON文件,内置可以使用。例如import Data from './data.json' CSVs, TSVs, XML, 等需要csv-loader,xml-loader。
npm install --save-dev csv-loader xml-loader
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
},
{
test: /\.(csv|tsv)$/,
use: [
'csv-loader'
]
},
{
test: /\.xml$/,
use: [
'xml-loader'
]
}
]
}
};
1. HtmlWebpackPlugin 使用hash文件名和多个bundle的时候,无法手动的在html里面,因为文件名称和文件数量一直在改变。那么需要使用HtmlWebpackPlugin来自动管理输出资源。它会在dist目录自动生成一个index.html,可以覆盖你自己的。
npm install --save-dev html-webpack-plugin
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js',
},
plugins: [
new HtmlWebpackPlugin({
title: 'Output Manament',
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
如果想使用更加丰富的配置index.html,可以使用html-webpack-template
2. 清除目录
npm install --save-dev clean-webpack-plugin
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js',
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Output Manament',
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
1. 使用source maps 打包后的代码到源代码的映射,出现错误或警告可以定位到源代码的具体位置。否则只能显示打包后代码的位置。 修改webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js',
},
devtool: 'inline-source-map', // 新加的。
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Development',
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'
},
};
可以进行相应的配置,source map 配置。
2. 选择合适的开发工具: 1)webpack's Watch Mode 可以指示 webpack "watch" 依赖图中的所有文件以进行更改。如果其中一个文件被更新,代码将被重新编译,所以你不必手动运行整个构建。但是并不会自动的刷新浏览器。 修改package.json:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch", // 新加的
"build": "webpack"
},
npm run watch
2)webpack-dev-server 提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。
npm install --save-dev webpack-dev-server
修改webpack.config.js.告知 webpack-dev-server,在 localhost:8080 下建立服务,将 dist 目录下的文件,作为可访问文件:
devServer: {
contentBase: './dist', // 告诉开发服务器(dev server),在哪里查找文件
},
修改package.json:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack-dev-server --open", // 新加的
"build": "webpack"
},
npm start
浏览器自动加载页面。如果现在修改和保存任意源文件,web 服务器就会自动重新加载编译后的代码.webpack-dev-server配置选项 3)webpack-dev-middleware 一个容器(wrapper),它可以把 webpack 处理后的文件传递给一个服务器(server)。webpack-dev-server内部使用的就是它,可以提供更加灵活的自定义配置。 配合express使用:
npm install --save-dev express webpack-dev-middleware
修改webpack.config.js.
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/' // publicPath 也会在服务器脚本用到,以确保文件资源能够在 http://localhost:3000 下正确访问
},
新建server.js
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const app = express();
const config = require('./webpack.config');
const compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
}));
app.listen(3001, function () {
console.log('webpack dev middleware on port 3001\n');
});
修改package.json:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack-dev-server --open",
"server": "node server.js",
"build": "webpack"
},
npm run server
浏览器没有自动加载页面,只是会重新编译,编译完后浏览器的代码仍是老代码,应该需要其他的相关热替换配置。
允许在运行时更新各种模块,而无需进行完全刷新。只适用于开发环境。没有启用HMR的话,修改文件相当于按了刷新键,浏览器会整个的完全重新刷新。而启用了HMR的话,只是局部刷新,没有更新的地方不会变,例如修改了页面的某段文本,改了某个文件后,可能仍是修改后的文本。
1. 启用HMR webpack-dev-server,使用内置的HMR插件。 webpack-dev-middleware,使用webpack-hot-middleware。 修改webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');
module.exports = {
entry: {
app: './src/index.js',
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
hot: true, // HMR
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Development',
}),
new webpack.HotModuleReplacementPlugin() // HMR
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'
},
};
这种启用方法并不会改变事件的回调函数,也就是说,如果callback改变了,点击事件调用的还是原来的callback。需要重新绑定。可以使用 ??? 来解决这个问题。
3. 处理css 只要安装了css-loader 和 style-loader,然后启用HMR就可以。
4. 实时调整react组件 react-hot-loader
移除无用代码dead code。使用import export。
1. 将文件标记为无副作用(side-effect-free)。 package.json 文件中添加一个配置
{
"name": "webpack-demo",
"side-effect": false, // "side-effect": ["./filename.js", "*.css"],
}
2. 压缩输出 -p编译标记,启用uglifyjs压缩插件 或者webpack.config.js的mode配置为production。
这章内容没看明白,还是不知道怎么弄生产环境
1. 配置 将原来的webpack.config.js 拆分为不同的文件webpack.common.js、webpack.dev.js、webpack.prod.js,然后使用工具webpack-merge进行合并。
npm install --save-dev webpack-merge
然后在package.json中的scripts进行运行:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack-dev-server --open --config webpack.dev.js",
"server": "node server.js",
"build": "webpack --config webpack.prod.js"
},
2. 压缩代码: UglifyJSPlugin BabelMinifyWebpackPlugin ClosureCompilerPlugin
3. source mapping dev: inline-source-map prod: source-map
4. 压缩css
把代码分离成不同的bundle,实现按需加载或并行下载。
1. 入口 entry points 可以配置多个entry。但是如果多个entry里面都import lodash,那么lodash将会被多次打包,放进多个bundle中。即,如果入口 chunks 之间包含重复的模块,那些重复模块都会被引入到各个 bundle 中。 可以用SplitChunks来移除重复。
2. 防止重复 CommonsChunkPlugin不被webpack 4支持,可以使用SplitChunksPlugin。 其他可使用的分离代码的plugins/loaders:mini-css-extract-plugin bundle-loader promise-loader
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
another: './src/another-module.js',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new CleanWebpackPlugin(['dist']),
],
optimization: {
splitChunks: {
chunks: 'all',
},
},
};
如果index.js 和 another-module.js都import 了lodash,那么将抽取出一个单独的bundle(vendors~another~index.bundle).
3. 动态import (1)使用import(),内部使用的是promise实现的。 (2)require.ensure
Prefetching/Preloading modules
bundle analysis
1. import()的使用 webpack.config.js
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
},
output: {
filename: '[name].bundle.js',
chunkFilename: '[name].chunk.bundle.js', // _按需加载的文件名,import()_
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin(),
],
};
index.js
import _ from 'lodash';
function component() {
var element = document.createElement('div');
var button = document.createElement('button');
var br = document.createElement('br');
button.innerHTML = 'click me and lok at the console';
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
element.appendChild(br);
element.appendChild(button);
button.onclick = e => {
console.log('before import.');
import(/* webpackChunkName: "print" */ './print.js').then(module => {
var print = module.default;
print();
})
console.log('after import.');
}
return element;
}
document.body.appendChild(component());
print.js
import moment from 'moment';
console.log('the print.js module has loaded!');
export default () => {
console.log('button clicked.', moment());
}
刷新页面,network:index.html index.bundle.js 输出: 无 第一次点击:vendors~print.chunk.bundle.js(print.js import moment, load moment.js) print.chunk.bundle.js(load print.js) 输出:before import after import the print.js module has loaded! button clicked (Moment object) 第二次点击:无 输出:before import after import button clicked (Moment object)
2. 在react中的使用,其他的见官网 react-router and react-loadable
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
},
output: {
filename: '[name].[contenthash].js', // contenthash, 每次内容改变时,生成不一样的hash值
// chunkFilename: '[name].chunk.bundle.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'caching'
}),
new webpack.HashedModuleIdsPlugin(),
],
optimization: {
runtimeChunk: 'single',
splitChunks: { // 对于相同的依赖每次生成的hash值相同,不必每次部署新的版本时都重新下载依赖库
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
}
}
}
}
};
步骤:
1.
创建目录结构
package.json增加private: true,去掉main: index.js
2. 上面的是命令行输入webpack的命令,我们可以使用配置文件进行webpack的配置。 新建webpack.config.js文件,输入以下内容(默认配置也是这样):
// 这里可以省略--config webpack.config.js。如果目录里存在webpack.config.js 文件,默认会使用这个文件的配置。
在命令行运行本地安装的npx命令仍然累赘,可以在npm 的scripts中加入运行webpack的命令。 修改package.json文件:
通过向 npm run build 命令和你的参数之间添加两个中横线,可以将自定义参数传递给 webpack,例如:npm run build -- --colors