模块化打包工具
网络资源的媒体类型,告知浏览器当前文件是什么类型,浏览器会根据该类型选择合适的形式展现。
名称 | 描述 |
---|---|
[ext] | 资源扩展名 |
[name] | 资源的基本名称 |
[path] | 资源路径 |
[hash] | 哈希值 |
// 大括号 多对多: 多个入口多个打包文件
entry:{
// 多入口文件
main:"src/main.js",
index:"src/index.js"
}
/*
// 中括号 多对一: 多个入口一个打包文件
entry: [
'src/index1.js',
'src/index2.js',
]
*/
/*
// 字符串 一对一 : 一个入口一个打包文件
entry: './src/index.js'
*/
output:{
publicPath:"http://cdn.....", // 相当于自动添加一个路径前缀
filename:"[name].js",
path:path.join(__dirname,"dist")
}
如果不开启 SourceMap ,那么一旦代码出现错误,会在打包生成的 js 文件中查找错误【 生成出来的 js 文件几乎是没法看的。。。 】,开启 SourceMap 可以在源文件代码中寻错。
// 如果 设置 mode : 'development' ,那么自动会开启 SourceMap
// devtool:none, // 可关闭 SourceMap【一般用于生产环境】
devtool: "source-map"; // 会在打包目录中自动生成一个 .map 的文件,这里面包含了映射关系
/*
"inline-source-map"; // 打开 sourceMap 会将映射关系写入到 生成的文件中
"cheap-inline-source-map" ; //打开 sourceMap 会将映射关系写入到 生成的文件中,并且告诉映射代码只需要映射到出错的行,不需要再映射出错的列,可以缩短出错代码的映射时间
"cheap-module-inline-source-map" ; // 除了自己的业务逻辑代码,同时也关注第三方模块的出错内容
"eval" ; // 最快的打包方式,eval 会以 js 字符串的形式打包,可以想想 eval 函数,另外虽然 eval 比较好用,但是对于一些比较复杂的代码,提示是不全面的
// 推荐:
devtool:'cheap-module-eval-source-map' // 开发环境中,可以更加详细也更快的列举出错的代码
*/
开启一段服务,用于提升用户的开发效率
// 会将 dist 目录中的代码先存放到内存,以便于更快的响应代码变更。
devServer: {
contentBase: path.join(__dirname, "dist"), // 将 dist 目录作为服务根地址
open: true, // 自动打开浏览器
port: 8000, // 端口
lazy: true,// 惰性模式, dev-server 只有在请求时才编译包(bundle)。这意味着 webpack 不会监视任何文件改动。
host: "0.0.0.0", // 这样方便局域网都可以访问
hot:true, // 打开热更替【 当代码变更的时候,可以只刷新部分内容,而不是整个网页都刷新 】
noInfo: true, // 隐藏编译信息,只显示错误和警告
hotOnly :true, // 当 Hot Module Replacement 没有生效的时候,也不要自动刷新页面
overlay: { // overlay的作用是可以在浏览器打开的页面显示终端编译时产生的错误,直接显示在页面上,不需要打开控制台
errors: true, // 显示错误信息
warnings: true // 显示警告信息
},
// 设置代理服务器 【 解决跨域 】
proxy: {
'/api': {
target: 'http://localhost:8001' // 将页面中所有以 /api 开头的请求都转发到 http://localhost:8001 该服务器下
}
}
/*
axios({
//url: 'http://locahost:8001/api/info', // 改成相对地址,不要直接访问服务器,而是通过服务器代理转发
url: '/api/info'
}).then(res => {
console.log(res);
})
// 最后服务端需要监听 8001 端口,并处理路由请求
*/
}
// 如果需要开启 热更替 ,那么还需要再引入一个插件
// 热更替可以只刷新部分代码,而不是改了一点代码就刷新网页
/*
// const webpack = require("webpack");
//.......
plugins:[
new webpack.HotModuleReplacementPlugin()
]
// 也可以在js模块代码中使用 module.hot.accept('test.js',()=>{}),监听 test.js 文件的变化,一旦变化会执行回调函数
*/
非 js 文件的打包方案
{
test:/\.(jpg|png|svg|jpeg|gif)$/,
use:{
loader:"url-loader", // 需要安装 file-loader
options:{
name:'[name].[ext]', // 采用自定义的图片名称
outputPath: 'assets/'
}
}
}
{
test:/\.(jpg|png|svg|jpeg|gif)$/,
use:{
loader:"url-loader", // 需要安装 file-loader \ url-loader
options:{
name:'[name]_[hash].[ext]', // 采用自定义的图片名称
outputPath:"static/", // 文件打包输出目录
limit:2048,// 当图片文件小于 2k 的时候直接打包成为 base64 编码加入到js 文件中,可以减少 http 请求
}
}
}
// style-loader 的作用是 把 `css-loader` 生成的内容,用 `style` 标签挂载到⻚面的 `head` 中
{
test:/\.css$/,
use:['style-loader','css-loader']
}
{
test:/\.less$/, // npm install --save-dev less-loader less
// loader 的执行顺序是 从下到上,从右到左
use:['style-loader','css-loader','less-loader']
}
// 利用 postcss-loader 【拥有大量的样式代码处理插件】
{
test:/\.less$/,
use:['style-loader','css-loader','less-loader','postcss-loader']
}
// postcss.config.js
/*
module.exports = {
plugins: [
require('autoprefixer') // 用于自动添加浏览器前缀
]
}
*/
{
test:/\.less$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:2, // 避免 less 的 @import 嵌套调用
modules:true// 开启 css 的模块化打包,不至于造成全局污染
}
},
'less-loader',
'postcss-loader'
]
}
// index.js
/*
import style from 'style.css'
img.classList.add(style.className) // 指定某元素使用某 class
*/
{
test:/\.(eot|ttf|svg|woff|woff2|otf)$/,
use:{
loader:'file-loader'
}
}
{
test: /\.(csv|tsv)$/,
use: [
'csv-loader'
]
},
{
test: /\.xml$/,
use: [
'xml-loader'
]
}
// npm i babel-loader @babel/core @babel/preset-env @babel/polyfill -D
// webpack.config.js
{
test:/\.js$/,
exclude:/node_modules/, // 排除掉 node_modules 里面的内容
loader:"babel-loader",
options:{
presets:[["@babel/preset-env",{// 高版本语法转换
useBuiltIns :'usage', // 只将使用到的函数语法进行转换
targets:{// 指定浏览器版本语法转换,一部分高版本浏览器已经对 ES6+ 的语法有很好的支持了,也就没有必要转换
chrome:"67",
}
}]]
}
}
// index.js
// import "@babel/polyfill" // 这一个引入可以将 js 文件中使用到的 高版本函数语法进行转换 【 不管有没有用到都会转换,所以上面配置了 useBuiltIns 】
/*
// 如果进行第三方模块的开发,或者组件开发,以及其他的可复用代码, @babel/polyfill 并不适用。因为 @babel/polyfill 会污染全局环境,一种替代方案【 不需要再使用 @babel/polyfill 】:
npm i @babel/plugin-transform-runtime @babel/runtime @babel/runtime-corejs2 -D
// webpack.config.js
{
test:/\.js$/,
exclude:/node_modules/,
loader:"babel-loader",
options:{
"plugins":[["@babel/plugin-transform-runtime",{
"corejs":2,
"helpers":true,
"regenerator":true,
"useESModules":false
}]]
}
}
// 或者将 options 里面的配置项放置到 .babelrc 文件中
// webpack.config.js
{
test:/\.js$/,
exclude:/node_modules/,
loader:"babel-loader",
}
// .babelrc
{
options:{
"plugins":[["@babel/plugin-transform-runtime",{
"corejs":2,
"helpers":true,
"regenerator":true,
"useESModules":false
}]]
}
}
*/
在 webpack 运行的某个时刻,自动处理程序代码
// npm i html-webpack-plugin -D
const htmlWebpackPluign = require("html-webpack-plugin");
// ...
plugins: [
// 打包之后会执行
new htmlWebpackPluign({
template: "src/index.html", // 使用 html 模板
}),
];
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
// ...
plugins: [
// 打包之前就会执行
new CleanWebpackPlugin(["dist"]),
];
CSS
到一个单独的文件中// npm i -D mini-css-extract-plugin
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
{
test: /\.css$/,
use: [
{loader: MiniCssExtractPlugin.loader},
'css-loader',
'sass-loader'
]
}
//...
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css'
}),
]