1.下载Node.js
进入官网 nodejs.cn/download/
选择对应的版本
按win+r
输入cmd打开命令行
输入node -v,显示版本则安装成功
D:\git-Warehouse\webpackDemo>node -v
v12.10.0
2.初始化项目
首先创建一个新目录
进入新目录里面
在当前目录下打开命令行窗口
输入 npm init
一路回车下去就行了
此时目录里面多了一个文件package.json
内容如下
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
3.安装Webpack
还是当前目录,执行命令
npm i webpack webpack-cli -D
此时目录如下
在命令终端使用npm i安装依赖关系时
如果带后缀 -D(或–save-dev) 安装的包会记录在"devDependencies"
下;
如果使用 --save后缀(我们后面会用到)安装的包会记录在"dependencies"
下。
两者的区别是:
“devDependencies”:dev开发时的依赖包
dependencies:程序运行时的依赖包
在此目录下创建一个src目录
进入scr目录,创建一个index.js文件
简单写个代码,比如
console.log("Hello, word")
切换到命令行
执行以下代码
npx webpack src/index.js
此时发现项目根目录下多了一个dist目录
在此目录下创建一个index.html,引入dist目录下的main.js
出现以下结果,打包成功
4.配置webpack
新建build目录
创建webpack.config.js文件
在里面添加以下配置
var webpack = require("webpack");
var path = require("path");
var DIST_PATH = path.resolve(__dirname, '../dist');
module.exports = {
entry: path.resolve(__dirname, "../src/index.js"),
output: {
path: DIST_PATH, // 创建的bundle生成到哪里
filename: 'bundle.js', // 创建的bundle的名称
},
module: {
},
plugins: [],
devServer: {
}
}
其中各项作用为
entry
:入口JS路径,指示Webpack应该使用哪个模块,来作为构建其内部依赖图的开始
output
: 编译输出的JS入路径,告诉Webpack在哪里输出它所创建的bundle,以及如何命名这些文件
module
:模块解析
plugins
:插件
devServer
:服务器配置
回到package.json
文件
添加以下代码
"scripts": {
"build": "webpack --config ./build/webpack.config.js --mode production",
"test": "echo \"Error: no test specified\" && exit 1"
}
这样我们可以不用输入
npx webpack src/index.js --output dist/bundle.js --mode none
直接用npm run build代替
其中“–mode production”表示项目的环境,不配置这个会报警告
输入npm run build重新打包
目录下多了一个我们自己定义的bundle
5.配置server服务
找到刚才编写的webpack.config.js,添加以下代码
devServer: {
hot: true, // 热更新,无需手动刷新 contentBase: DIST_PATH,
// host: '0.0.0.0', // host地址
port: 8080, // 服务器端口
historyApiFallback: true,// 该选项的作用所用404都连接到index.html
proxy: {
"/api": "http://localhost:3000" // 代理到后端的服务地址,会拦截所有以api开头的请求地址
}
}
和build类似,需要在package.json的scripts中添加相关的命令
在package.json中
"scripts": {
"build": "webpack --config ./build/webpack.config.js --mode production",
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --config ./build/webpack.config.js --mode development --open"
},
安装webpack-dev-server
npm i webpack-dev-server -D
运行npm run dev,打开localhost:8080,就可以看见网站
注意!!!!
开发不能设置output的publicPath,否则页面出不来,因为找不到路径,使用默认的就好了
可以如下设置
判断当前环境
const devMode = process.env.NODE_ENV === 'production'
动态publicPath
output: {
// 编译输出的JS入路径
// 告诉Webpack在哪里输出它所创建的bundle,以及如何命名这些文件
path: DIST_PATH, // 创建的bundle生成到哪里
filename: 'js/[name].js', // 创建的bundle的名称
publicPath: devMode ? './' : "",
},
现在还不能直接运行,得安装一个插件
6.自动生成index.html
安装插件
npm install --save-dev html-webpack-plugin
首先引入我们的插件
let HtmlWebpackPlugin = require('html-webpack-plugin');
在配置文件中添加
plugins: [
new HtmlWebpackPlugin(),
],
同时,HtmlWebpackPlugin方法里可以接受一个对象, 如指定模板文件
new HtmlWebpackPlugin({
template: "./src/index.html"
})
此时打包生成的网页文件,除了你webpack中绑定的数据,还有你模板中的代码
打开命令行,输入npm run dev
demo地址 github.com/ZengHaiTao1…
7.生成前先清楚dist文件夹
安装对应插件
npm install --save-dev clean-webpack-plugin
在配置文件中引入插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
添加在配置文件最前面
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Output Management',
}),
],
8.加载css
8.1.安装所需要的模块
npm install --save-dev css-loader
npm install --save-dev style-loader
8.2.在webpack.config.js配置文件中配置module
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
};
其中‘style-loader’一定要写在前面
8.3.options选项
module: {
rules: [ //配置加载器, 用来处理源文件, 可以把es6, jsx等转换成js, sass, less等转换成css
{
test: /\.css$/, //配置要处理的文件格式,一般使用正则表达式匹配
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: true, // 指定启用css modules
}
}
]
}
]
},
9加载scss
安装对应的解析器
npm install sass-loader node-sass --save-dev
在配置文件中添加以下代码
// webpack.config.js
module.exports = {
...
module: {
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader" // 将 JS 字符串生成为 style 节点
}, {
loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
}, {
loader: "sass-loader" // 将 Sass 编译成 CSS
}]
}]
}
};
就可以正常使用scss文件了
测试css
在src目录下新建static目录,创建css目录,index.css文件
定义背景色
在index.jsyin
输入npm run dev 打开 网页
测试scss
修改后缀名
修改配置文件
module: {
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader" // 将 JS 字符串生成为 style 节点
}, {
loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
}, {
loader: "sass-loader" // 将 Sass 编译成 CSS
}]
}]
},
启动项目,正常运行。
10.加载图片
npm install file-loader --save-dev
配置模块加载器
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
// options: {
// name(file) {
// if (process.env.NODE_ENV === 'development') {
// return '[path][name].[ext]';
// }
// return '[name].[ext]';
// },
// outputPath: 'images',
// }
},
],
},
图片的使用方法
1.在主页中
直接引入打包后的路径
<img src="'xxx.jpg'"/>
2.在模板页中,模板页里的img 标签中相对路径的图片不会被loader 解析,因此需要使用require 引用图片
<img src="${require('xxx.jpg')}"/>
11.配置url-loader
安装解析器
npm install url-loader --save-dev
{
test: /\.(png|svg|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
name: 'images/[name].[ext]',
limit: 1024
}
}
},
12.优化Webpack配置
在build文件夹下创建三个文件
公共配置:把开发和生产环境需要的配置都集中到公共配置文件中,即webpack.common.js
开发环境配置:把开发环境需要的相关配置放置到webpack.dev.js
生产环境配置:把生产环境需要的相关配置放置到webpack.prod.js
为了更好的管理和维护这三个文件,需要安装一个webpack-merge插件:
npm i webpack-merge -D
在公共配置文件webpack.common.js文件中添加相应的配置
const webpack = require('webpack');
const path = require('path');
const DIST_PATH = path.resolve(__dirname, '../dist/'); // 声明/dist的路径
module.exports = {
// 入口JS路径
// 指示Webpack应该使用哪个模块,来作为构建其内部依赖图的开始
entry: path.resolve(__dirname, '../src/index.js'), // 编译输出的JS入口路径
// 告诉Webpack在哪里输出它所创建的bundle,以及如何命名这些文件
output: {
path: DIST_PATH, // 创建的bundle生成到哪里
filename: 'main.js', // 创建的bundle的名称
},
// 模块解析
module: {},
// 插件
plugins: []
}
接着给Webpack开发环境配置文件webpack.dev.js添加下面的相关配置:
const webpack = require('webpack');
const path = require('path');
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const DIST_PATH = path.resolve(__dirname, '../dist/'); // 声明/dist的路径
module.exports = merge(commonConfig, {
mode: 'development', // 设置webpack mode的模式
// 开发环境下需要的相关插件配置
plugins: [ ],
// 开发服务器
devServer: {
hot: true, // 热更新,无需手动刷新
contentBase: DIST_PATH,
// host: '0.0.0.0', // host地址
port: 8080, // 服务器端口
historyApiFallback: true, // 该选项的作用所用404都连接到index.html
proxy: {
// 代理到后端的服务地址,会拦截所有以api开头的请求地址
"/api": "http://localhost:3000"
} }
})
继续给Webpack生产环境配置文件webpack.prod.js添加相关配置:
const webpack = require('webpack');
const path = require('path');
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
module.exports = merge(commonConfig, {
mode: 'production', // 设置Webpack的mode模式
// 生产环境下需要的相关插件配置
plugins: [ ],
})
同时,我们要修改package.json中的scripts中的信息
"scripts": {
"build": "webpack --config ./build/webpack.prod.js --mode production",
"dev": "webpack-dev-server --config ./build/webpack.dev.js --mode development --open", "test": "echo \"Error: no test specified\" && exit 1" },
13.使用source map功能, 跟踪源文件错误
正常我们编译的js代码报错是直接显示报错信息的,是编译之后的出错位置,不显示源文件中哪里出错,不利于我们调试
我们可以在配置文件中配置devtool来解决这一问题
设置devtool
1、source-map:产生文件,产生行列
2、eval-source-map:不产生文件,产生行类
3、cheap-source-map:产生文件,不产生列
4、cheap-module-eval-source-map:不产生文件,不产生列
更多选项可查看官网devtool配置 webpack.js.org/configurati…
在本地调试时,我们可以设置为devtool: ‘inline-source-map’,
用于说明性目的(但不适合制作)。
14 从js中分离css
安装插件
npm install --save-dev mini-css-extract-plugin
修改配置文件
{
test: /\.(sa|sc|c)ss$/, // 可以打包后缀为sass/scss/css的文件
use: [
{
loader: MiniCssExtractPlugin.loader,
},
},
{
loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
}, {
loader: "sass-loader" // 将 Sass 编译成 CSS
}
],
},
使用插件
new MiniCssExtractPlugin({
// 这里的配置和webpackOptions.output中的配置相似
// 即可以通过在名字前加路径,来决定打包后的文件存在的路径
filename: devMode ? 'css/[name].css' : 'css/[name].[hash].css',
chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash].css',
}),
最基础的配置就完成了
现在根据运行环境动态配置
const devMode = process.env.NODE_ENV !== 'production'
在MiniCssExtractPlugin.loader模块解析中添加选项
publicPath公共输出目录
如下
publicPath: devMode ? '../' : './', // 根据不同环境指定不同的publicPath
hmr: devMode, // 仅dev环境启用HMR功能
一般打包后路径出现问题,就与这个路径有关
同时在我们的插件配置里
filename: devMode ? 'css/[name].css' : 'css/[name].[hash].css',
chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash].css',
15.多页面开发
1.在src目录下创建文件夹page1,page2
2.修改配置文件入口
entry: {
main1: path.resolve(__dirname, "./src/page1/index.js"),
main2: path.resolve(__dirname, "./src/page2/js/main2.js"),
},
3.修改出口
output: {
// 编译输出的JS入路径
// 告诉Webpack在哪里输出它所创建的bundle,以及如何命名这些文件
path: DIST_PATH, // 创建的bundle生成到哪里
filename: 'js/[name].js', // 创建的bundle的名称
publicPath: '../',
},
其中注意filename
不能固定死!
3.修改HtmlWebpackPlugin插件配置
new HtmlWebpackPlugin({
filename: __dirname + '/dist/page1/index.html',
template: __dirname + "/src/page1/index.html",
chunks: ['main1'],
inlineSource: '.(js|css)$'
}),
new HtmlWebpackPlugin({
filename: __dirname + '/dist/page2/index.html',
template: __dirname + "/src/page2/index.html",
chunks: ['main2'],
inlineSource: '.(js|css)$'
}),
chunks中写你页面所依赖的输出配置文件
到这里,一个简单的单页面配置就完成了。
16.分离公共css,js
使用SplitChunksPlugin
这个webpack 4+ 版本已经内置
修改配置文件,加入以下代码
optimization: {
splitChunks: {
cacheGroups: {
//打包公共模块
commons: {
chunks: 'initial', //initial表示提取入口文件的公共部分
minChunks: 2, //表示提取公共部分最少的文件数
minSize: 0, //表示提取公共部分最小的大小
name: 'commons' //提取出来的文件命名
}
}
}
}
同时,我们要修改HtmlWebpackPlugin 插件,将所提取出来的commons注入到页面中去
chunks: ['main1', "commons"],
17.使用glob动态配置入口
安装glog
npm install glob -save-dev
glob可以用来匹配路径
var glob = require("glob")
// options is optional
glob("**/*.js", options, function (er, files) {
// 文件是文件名数组。
// 如果设置了`nonull`选项,则什么也没有
// 被发现,则文件为[“ ** / *。js”]
// er是错误对象或null。
})
第一个参数可以用以下方式匹配
在路径部分中使用下列字符具有特殊的神奇含义:
*匹配单个路径部分中的0或多个字符。
?匹配1字符
[...]匹配一系列字符,类似于RegExp范围。如果范围的第一个字符是!或^然后它匹配任何不在范围内的字符。
!(pattern|pattern|pattern)匹配任何不匹配提供的任何模式。
?(pattern|pattern|pattern)匹配所提供的模式的零或一次。
+(pattern|pattern|pattern)匹配一个或多个提供的模式。
*(a|b|c)匹配所提供的模式的零次或更多次。
@(pattern|pat*|pat?erN)与所提供的模式之一完全匹配。
**如果“珠星”单独存在于路径部分,则匹配零个或多个目录和搜索匹配的子目录。它不爬行符号链接目录。
*和**的使用方法
glob("./src/components/**/*.js", function (er, files) {
console.log(files);
return files
});
// [ './src/components/index/index.js',
// './src/components/news/n.js',
// './src/components/news/news.js' ]
?的使用方法
glob("./src/components/**/?.js", function (er, files) {
console.log(files);
return files
});
//[ './src/components/news/n.js' ]
有几个“?”就匹配几个字符
[…]的使用方法
glob("./src/components/**/inde[a-z].js", function (er, files) { console.log(files) }) //[ './src/components/index/index.js' ]
匹配满足[a-z]条件的路径,相比?方法匹配更为精准一些
?()的使用方法
glob("./src/components/**/?(news|index|n).js", function (er, files) {
console.log(files)
});
// [ './src/components/index/index.js',
// './src/components/news/n.js',
// './src/components/news/news.js' ]
+()的使用方法
glob("./src/components/**/+(in|news|dex).js", function (er, files) {
console.log(files)
});
// [ './src/components/index/index.js',
// './src/components/news/news.js' ]
本案例中会匹配in.js,news.js,dex.js,innews.js,index.js,newsdex.js 他会先匹配自身是否会匹配上,然后在和其他模式组合在进行匹配。
@()的使用方法
他会完整匹配备选模式中的其中一个,只要有一个模式匹配上就会被匹配
glob("./src/components/**/@(index|n|news).js", function (er, files) {
console.log(files)
});
// [ './src/components/index/index.js',
// './src/components/news/n.js',
// './src/components/news/news.js' ]
!()的使用方法,理解为反的意思,其实这个没什么说的, 稍微懂点js的都会。和运算表达式中的!一样。
案例中的意思是不要n.js 不要index.js,所以就只剩下new.js了。
glob("./src/components/**/!(n|index).js", function (er, files) {
console.log(files)
})
// [ './src/components/news/news.js' ]
在上述案例中使用的都是异步请求,调用回调得到结果,其实glob也提供了同步返回结果的API ,在这里我只列举一个。
let pattern = './src/components/**/@(index|n|news).js';
console.log(glob.sync(pattern));
// [ './src/components/index/index.js',
// './src/components/news/n.js',
// './src/components/news/news.js' ]
const glob = require("glob")
匹配路径
const htmls = glob.sync("src/page?/page?.js")
我的目录结构为
所以匹配到的是
src/pagea/pagea.js
src/pageb/pageb.js
接着定义一个 entrys对象,定义一个 htmlCfg数组,htmlCfg数组添加到插件解析上
htmls.forEach(filePath => { // "src/page1/page1.js"
let path = filePath.trim().split('/'); //分割路径, ['src', 'page1', 'page1.js'], 放进 path 数组里
let file = path.pop(); //'page1.js'
let name = file.split(".")[0]; //page1
entrys[name] = "./" + filePath
htmlCfgs.push(
new HtmlWebpackPlugin({
template: "./src/" + name + "/" + name.trim() + ".html", // "./src/page1/page1.html"
chunks: ["./dist/" + name, 'commons'],
filename: name + ".html",
inlineSource: '.(js|css)$'
})
)
});
调用js函数获取文件名,以及所需要的路径,如上
接着修改配置文件
将entrys和htmlCfg加在配置文件中
entry: entrys,
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
// 这里的配置和webpackOptions.output中的配置相似
// 即可以通过在名字前加路径,来决定打包后的文件存在的路径
filename: devMode ? 'css/[name].css' : 'css/[name].[hash].css',
chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash].css',
}),
].concat(htmlCfgs)
18.使用babel解析es6语法
bael是什么
Babel 是一个让我们能够使用 ES 新特性的 JS 编译工具,我们可以在 webpack 中配置 Babel,以便使用 ES6、ES7 标准来编写 JS 代码。 Babel是JavaScript编译器 Babel是一个工具链,主要用于在当前和较旧的浏览器或环境中将ECMAScript 2015+代码转换为JavaScript的向后兼容版本。以下是Babel可以为您做的主要事情:
// Babel Input: ES2015 arrow function
[1, 2, 3].map((n) => n + 1);
// Babel Output: ES5 equivalent
[1, 2, 3].map(function(n) {
return n + 1;
});
安装babel-loader 和 @babel/core
npm i -D babel-loader
npm i -D @babel/core
配置babel-loader模块解析
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: { loader: 'babel-loader' } // options 在 .babelrc 定义
}
打开我们的js入口文件,编写es6代码
const func = () => {
console.log('hello webpack')
}
func()
class User {
constructor() {
console.log('new User')
}
}
const user = new User()
在配置文件中添加
mode: "development",
因为webpack4已经为我们配置了css,js代码压缩,默认生产环境开启
此时打包项目
发现es6语法,并没有转换
安装@babel/preset-env
这个包包含了 es6+ 的语法转换规则,如箭头函数、const 等
同时我们安装@babel/polyfill
这个包可以让我们使用es6 内置对象和函数的垫片,如 Promise、Array.from 等
安装完之后,在根目录下创建 .babelrc 文件,进行一些简单配置:
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
]
]
}
在babel7的版本我们可以采用babel.config.js进行配置
// babel.config.js
module.exports = function (api) {
api.cache(true)
const presets = [
[
"@babel/preset-env",
{
"useBuiltIns": "usage"
}
]
]
const plugins = [
[
"@babel/plugin-transform-runtime",
{
"corejs": 2
}
]
]
return {
presets,
plugins
}
}
看网上说要在入口js文件中加上import ‘@babel/polyfill’
我试了一下 不加可以正常解析
大概是版本的问题吧。
打包后发现,Js文件过大,把一些不需要的语法也打包进来了
此时我们修改.babelrc文件
useBuiltIns: “usage”, “entry”, “false”。默认为 false。
usage: 在每个文件中使用 polyfill 时,为 polyfill 添加特定导入,babel 利用捆绑器只加载一次相同的polyfill。
entry: 使用 entry 属性,必须在项目入口处引入一次 @babel/polyfill。然后 babel 在做代码转换的时候,会把
将 .babelrc 下的useBuiltIns改为usage,再执行转换命令,就会发现 polyfill 变成了按需导入。
** babel 7 还提供了targets,这个配置主要用于指定需要支持的环境,一般是指浏览器版本。( targets 还可以指定 node、android、ios、electron 等其他环境)**
设置了 targets,babel 在转换前,会先检查 targets 指定的环境已经支持了哪些新语法和 API,然后就不再转换或者不引入已经支持的内容。
@babel/plugin-transform-runtime、@babel/runtime
使用 @babel/polyfill 会对全局对象进行污染,所以可以使用 @babel/plugin-transform-runtime 和@babel/runtime 防止这种现象。
@babel/plugin-transform-runtime 会在你需要的地方自动引入你使用到的新方法。
修改 .babelrc 文件:
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage"
}
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": 2
}
]
]
}
看了上面的做法,你可能会觉得困惑,为什么要一起使用 @babel/plugin-transform-runtime、@babel/runtime 呢,为什么不能单独使用一个?
其实是因为 babel 转换时,@babel/plugin-transform-runtime 这个插件会自动引入使用到的新方法,而引入的这些 polyfill 包是在 @babel/runtime 里面的,所以 @babel/runtime 需要安装在 dependency(生产环境)下,@babel/plugin-transform-runtime 则安装在 devDependency(开发环境)下。
同时,博主运行的时候报错,找不到"@babel/runtime-corejs2": "^7.7.5"模块
最后安装**@babel/runtime-corejs2": "^7.7.5**,配置到这里就结束了。
19.引入第三方库的三种方法
1.通过html页面script标签引入
通常是采用CDN
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>.js
//网上说要配置这么一段,我试过了好像不用,先贴上来,你们可以尝试一下
// 入口文件
import $ from 'jquery'
console.log($)
//webpack配置
module.exports = {
externals: {
jquery: 'jQuery'
}
}
在html文件中引入了之后,就可以在入口文件(app.js)中,使用 $(function(){}) 了
2.通过NPM包引入
以jq为例子
npm install jquery --save;
然后我们在配置文件中配置
plugins:[
new webpack.ProvidePlugin({
$:"jquery", //这里的意思是就把 $ 注入模块中 , 而后面的jquery 就是node_modules目录下的jquery
})
]
同时我们可以将第三方库分离出来
optimization: {
splitChunks: {
chunks: "all", // async表示抽取异步模块,all表示对所有模块生效,initial表示对同步模块生效
cacheGroups: {
//打包公共模块
// vendors: { // 键值可以自定义
// //chunks: 'initial', //initial表示提取入口文件的公共部分
// minChunks: 1, // 代码块至少被引用的次数
// test: /[\\/]node_modules[\\/]/,
// name: "vendors", // 入口的entry的key
// // enforce: true // 强制
// // priority: -10 //抽取优先级
// }
}
}
},
配置完成后所有通过npm引入的第三方库将被打包成vendors.js,没有使用过的第三库不会被打包
3.引入本地第三方库
这种也是网上最少的一种,博客花了三个小时左右才真正解决问题,网上大多都是讲npm引入,或者就是本地引入方法出问题
简单说一下
第一种。
通入入口文件引入
entrys["vendors"] = ["./src/lib/jquery-3.2.1.js"]
一定要把使用的库放在前面
然后在HtmlWebpackPlugin插件中配置
chunks: ["vendors", name, 'commons',],
缺点:不管有没有使用,都会被打包进js文件
第二种
直接在入口js通过路径引入
import "./../lib/jquery-3.2.1.js"
然后就可以使用了
看到这里,小伙伴们可能会疑问
这样的话为什么不直接定义个webpack.ProvidePlugin和通过NPM包引入引入一样了
试过
我先配置了模块别名
resolve: {
alias: {
// vue$: path.resolve(__dirname, "./src/lib/vue.js"),
// vue: path.resolve(__dirname, "./src/lib/qqq.js"),
// jquery: path.resolve(__dirname, "./src/lib/jquery-3.2.1.js"),
}
},
然后和npm包引入一样的方法
new webpack.ProvidePlugin({
// $: 'jquery',
// jQuery: 'jquery',
// "window.$": 'jquery',
// "window.jQuery": 'jquery',
})
结果控制台报错,$没有定义,然后我又安装了expose-loader,试图把JQ抛出到全局变量
配置如下
// test: require.resolve(path.resolve(__dirname, "./src/lib/jquery-3.2.1.js")),
// use: [{
// loader: 'expose-loader',
// options: 'jQuery'
// }, {
// loader: 'expose-loader',
// options: '$'
// }]
// },
结果依然显示没有定义
再后来博主通过imports-loader将模块直接导入入口js文件
// {
// test: path.resolve(__dirname, "./src/pagea/pagea.js"),
// exclude: /node_module/,
// use: [{
// loader: "imports-loader",
// options: {
// $: 'jquery',
// jquery: 'jquery'
// }
// }
// ]
// },
依然是提示,$没有定义,以上情况,JQ均打包进了js文件中,切在文件顶部
博主在引入本地第三方库上花了大量时间,
总结,能用npm引入就用npm引入,不能使用npm引入的第三方库,可以采用上面两种方法引入 能用谷歌就用谷歌,百度了一大堆,能看的,能用的就那么两三个。
20.删除没有使用过的css代码
安装依赖
npm i -D purifycss-webpack purify-css
修改配置文件
new PurifyCSSPlugin({
// Give paths to parse for rules. These should be absolute!
paths: glob.sync(path.join(__dirname, './src/**/*.html')),
})
21.自动添加css前缀
webpack打包时,css自动添加浏览器前缀。我们需要用到一个Loader:postcss-loader,和一个插件:autoprefixer
npm i -D postcss-loader autoprefixer
配置解析器
{
test: /\.(sa|sc|c)ss$/, // 可以打包后缀为sass/scss/css的文件
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// 这里可以指定一个 publicPath
// 默认使用 webpackOptions.output中的publicPath
// publicPath的配置,和plugins中设置的filename和chunkFilename的名字有关
// 如果打包后,background属性中的图片显示不出来,请检查publicPath的配置是否有误
// publicPath: './',
publicPath: devMode ? '../' : './', // 根据不同环境指定不同的publicPath
hmr: devMode, // 仅dev环境启用HMR功能
},
},
{
loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
}, {
loader: "sass-loader" // 将 Sass 编译成 CSS
}, {
loader: "postcss-loader"
}
],
},
把**“postcss-loader”**放在最后
然后在webpack.config.js文件同级目录中,新建postcss.config.js文件,并且添加如下代码:
module.exports = {
plugins:[
require('autoprefixer')
]
}
同时我们也可以不创建postcss.config.js配置文件,直接在主配置文件中引入
{
loader: "postcss-loader",
options: {
plugins: [
require('autoprefixer')//postcss-loader会叫autoprefixer插件添加浏览器前缀
]
}
}
使用tx-loader解析typescript
npm install --save-dev typescript
npm install --save-dev ts-loader
{
"compilerOptions": {
"outDir": "./dist/",
"noImplicitAny": true,
"module": "commonjs",
"target": "es6",
"allowJs": true,
"sourceMap": true
}
}
配置解析器
resolve: {
extensions: [".ts", ".tsx", ".js"]
},
{
test: /\.ts|.tsx$/,
exclude: [
path.resolve(__dirname, 'node_modules'),
],
use:
{
// loader: 'ts-loader',
loader: 'ts-loader',
},
},
然后就可以在项目中正常使用typeScript了
使用babel解析typescript
npm install --save-dev @babel/preset-typescript
修改babel.config.js配置文件 babel7之后可以使用babel.config.js作为配置文件
// babel.config.js
module.exports = function (api) {
api.cache(true)
const presets = [
[
"@babel/preset-env",
{
"useBuiltIns": "usage"
}
],
[
'@babel/preset-typescript',
{
allExtensions: true, // 支持所有文件扩展名
},
],
]
const plugins = [
[
"@babel/plugin-transform-runtime",
{
"corejs": 2
},
"transform-typescript"
]
]
return {
presets,
plugins
}
}
修改webpack配置文件,模块解析
{
test: /\.ts|.tsx$/,
exclude: [
path.resolve(__dirname, 'node_modules'),
],
use:
{
// loader: 'ts-loader',
loader: 'babel-loader',
},
},
22.使用pug模板
pug是什么
Pug是一款健壮、灵活、功能丰富的HTML模板引擎,专门为 Node.js 平台开发。Pug是由Jade 改名而来。
是一种通过缩进(表示标签间的嵌套关系)的方式来编写代码的过程,在编译的过程中,不需要考虑标签是否闭合的问题。可以加快写代码速度,也为代码复用提供了便捷。
类别的话,可以理解为,scss,typescript,这种需要编译的,编程式语言
安装依赖
npm install pug pug-html-loader raw-loader --save-dev
配置解析
{
test: /\.pug$/,
loader: ["raw-loader", 'pug-html-loader']
,
}
在vscode中配置pug模板
"Pug": {
"prefix": "pug",
"body": [
"doctype html",
"html(lang='en')",
"head",
"meta(charset='UTF-8')",
"meta(name='viewport', content='width=device-width, initial-scale=1.0')",
"meta(http-equiv='X-UA-Compatible', content='ie=edge')",
"title Document",
"body"
],
"description": "pug"
}