// webpack内部有一个事件流,tapable 1.0
let path = require('path');
let $ = require('jquery');
let webpack = require('webpack')
// 压缩js代码
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
// 生成html模版
var HtmlWebpackPlugin = require('html-webpack-plugin');
// 提取css文件
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
let pages = ['index', 'copy', 'main']
// const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
let cssExtract = new ExtractTextPlugin('css/[name].css')
let lessExtract = new ExtractTextPlugin('css/[name].less')
let sassExtract = new ExtractTextPlugin('css/[name].scss')
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin')
module.exports = {
// entry 可以放一个字符串,可以放数组
// 放一个对象: 多入口, 先找到每个入口,然后从各个入口分别出发,找到依赖的模块(module)
// 然后生成一个chunk(代码块),最后把chunk写到文件系统中(Assets)
entry: { // 入口, 多入口
index: './src/index.js',
copy: './src/copy.js',
main: './src/main.js'
}
// 可以注入公共代码,第三方依赖
vendor: ['jquery'] ,
output: {
path: path.join(__dirname, 'dist'), // 输出的文件夹,只能是绝对路径
filename: '[name].[hash:8].js' // name是entry名字main, hash是根据文件内容生成的
},
resolve: {
// 引入模块不加扩展名,按顺序查找
extensions: ['.js', '.json'],
alias: {
// 配置别名
'@': '/src'
}
},
// 监控源文件的变化,重新打包
watch: true,
watchOptions: {
ignored: /node_modules/,
poll: 1000, // 每秒问1000次
aggregateTimeout: 500 //节流,不会立即开始编译
},
// 上线不要放上去,不安全,devtool有如下四种形式
devtool: 'source-map', // 单独文件,可以定位到那一列出错
// devtool: 'cheap-module-source-map', // 单独文件,体积更小,但是只能定位到那一行出错
// devtool: 'eval-source-map', // 不会生成单独文件
// devtool: 'cheap-module-eval-source-map', // 不会生成单独文件,体积更小,但是只能定位到那一行出错
module: {
rules: [
// loader有三种写法
// 1.use
// 2.loader
// 3.use + loader
// 用babel解析语法, yarn add babel-loader @babel-core babel-preset-env babel-preset-stage-0 babel-preset-react -D
{
test: /\.js/,
use: {
loader: 'babel-loader',
query: {
// 指定预设
"presets": ["react", "env", 'stage-0']
// modules: false 不要把es6module语法解析成es5的语法,用于shaking
// "presets": ["react", "env", {modules: false}] // 分别是es6,es7,react
}
}
},
// 把页面中的css单独提出来打包, 用插件和loader,就不用下面的style-loader了
// extract-text-webpack-plugin 由于extract-text-webpack-plugin目前还没有webpack4版本。可以使用该方式npm install extract-text-webpack-plugin@next
{
test: /\.css$/, // 转换文件的匹配正则
// css-loader用来解析处理css文件中的url路径, 把css文件变成一个模块
// style-loader 可以把css文件变成style标签插入head中
// 多个loader是顺序要求的,从右往左写,因为转换的时候是从右往左转换
use: cssExtract.extract({
fallback: "style-loader",
use: ["css-loader", 'postcss-loader'] // 自动添加前缀用postcss-loader autoprefixer
})
},
{
test: /\.less$/, // 转换文件的匹配正则
use: lessExtract.extract(["css-loader", 'less-loader']
)
}, {
test: /\.scss$/, // 转换文件的匹配正则
use: sassExtract.extract(["css-loader", 'sass-loader']
)
},
{ // 得到模块的绝对路径, 注入全局变量
test: require.resolve('jquery'),
// loader: 'expose-loader?$'
use: {
loader: 'expose-loader',
options: '$'
}
},
// 编译less和sass, 需要安装less node-sass less-loader sass-loader
{
test: /\.(less)$/i,
loader: ['style-loader', 'css-loader', 'less-loader']
},
{
test: /\.(scss)$/i,
loader: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.css$/, // 转换文件的匹配正则
loader: ['style-loader', 'css-loader']
},
// url-loader可以在文件比较小的时候,直接变成base64内嵌到页面里面, 用了它就不要用file-loader
{test: /\.(png|jpg|gif|svg|bmp|ttf|woff)/,
use: {
loader: 'url-loader',
options: {
limit: 5 * 1024,
outputPath: 'images/' // 指定输出目录
}
}
},
{
// 这个file-loader可以处理任意的二进制,字体,图片从源文件拷贝到目标目录
test: /\.(png|jpg|gif|svg|bmp)/,
use: {
loader: 'file-loader',
options: {
outputPath: 'images/' // 指定输出目录
}
}
},
// 可以解析html里面的img的src
{
test: /\.(htm|html)$/i,
loader: 'html-withimg-loader'
},
]
},
// 提取公共代码
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
automaticNameMaxLength: 30,
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2, // 最少两个文件包含才是公共的
priority: -20,
reuseExistingChunk: true
}
}
}
},
plugins: [
cssExtract, // 把页面中的css单独提出来打包
lessExtract, // 把页面中的less单独提出来打包
sassExtract, // // 把页面中的sass单独提出来打包
//下面两个配合hot热更新,不常用,可以不知道
// new webpack.HotModuleReplacementPlugin(),
// new webpack.NamedModulesPlugin(), // 用名称代替id
new CopyPlugin([ // 拷贝不要编译的源文件到打包文件里面
{ from: path.resolve(__dirname, 'src/public'),
to: path.resolve(__dirname, 'dist/public')}
]),
new MiniCssExtractPlugin({ // css代码压缩
// Options similar to the same options in webpackOptions.output
// all options are optional
filename: '[name].css',
chunkFilename: '[id].css',
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
// 自动向模块内部注入变量
new webpack.ProvidePlugin({
$: 'jquery'
}),
// 自动清除dist目录
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [path.join(__dirname, 'dist')]
}),
// 此插件可以自动产出html文件,一般项目会放一个模版html用于打包
...pages.map(item => {
return new HtmlWebpackPlugin({
template: './src/index.html', // 指定产出的模版
filename: `${item}.html`, // 产出的html文件名
title: `${item}`, // 可以使用变量
chunks: [`${item}`, 'vendor'], // 在产出的html文件里引入哪些代码块, 跟多入口的entry对应
hash: true, //可以清除缓存,会在资源后面加上?hash
minify: {
removeAttributeQuotes: true
}
})
}),
// scope hositing,减少函数声明,把函数合并
new webpack.optimize.ModuleConcatenationPlugin(),
],
// 压缩js
optimization: {
minimizer: [new UglifyJsPlugin()],
},
// 配置此静态文件服务器,可以用来预览打包后的项目,是放到内存中的文件,有缓存,304
devServer: {
//热加载
hot: true,
inline: true,
contentBase: './dist',
host: 'localhost', // 访问的host
port: 8080, // 端口
compress: true, // 服务器返回给客户端的时候是否开启gzip压缩
}
}
webpack4基本配置
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...