webpack是一个现代的JavaScript应用的静态模块打包工具。
webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。
而且不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做模块来使用
就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。
我们可以配置一系列的task,并且定义task要处理的事务(例如ES6、ts转化,图片压缩,scss转成css)
之后让grunt/gulp来依次执行这些task,而且让整个流程自动化。
所以grunt/gulp也被称为前端自动化任务管理工具。
如果你的工程模块依赖非常简单,甚至是没有用到模块化的概念。
只需要进行简单的合并、压缩,就使用grunt/gulp即可。
但是如果整个项目使用了模块化管理,而且相互依赖非常强,我们就可以使用更加强大的webpack了。
grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心。
webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是它附带的功能。
我是直接根据以前的package.json安装的包 ,以前已经安装过了。(全局)
webpack src/main.js -o build/built.js --mode=development
一般都需要全局安装后再局部安装。由于我们的项目需要的版本不是全局的4点几的版本,
我在局部:npm i [email protected] webpack-cli -D
而且在终端执行命令时,如果直接用webpack,那么使用的一定是全局的。
这时,我们可以在package.json里面配置scripts,
比如这里,npm run build 即等于执行webpack命令。
package.json中的scripts的脚本在执行时,会按照一定的顺序寻找命令对应的位置。 首先,会寻找本地的node_modules/.bin路径中对应的命令。 如果没有找到,会去全局的环境变量中寻找。
所以这样配置了,就可以解决使用局部的webpack.
style-loader,css-loader,less-loader,less
npm i css-loader style-loader --save-dev
npm i [email protected] [email protected] -D(有时会因为版本问题报错,这里采用这个版本)
方法将"html-webpack-plugin"版本由 "^4.2.0"改为 "^3.2.0",
npm uninstall html-webpack-plugin
npm install [email protected] -D
参照老师的教程,加什么publicPath:'build/',结果出错了。(想着这样才可以访问原来的图片)
我还是采用了以前学webpack4的时候,用html-webpack-plugin ,这样把原来的html文件作为模板加入到输出文件夹。并且它会自动引入导出的那个bundle.js文件。
// const path = require('path')
const {resolve}=require('path')
const HtmlWebpackPlugin=require('html-webpack-plugin')
module.exports = {
entry: './src/main.js',
output: {
path: resolve(__dirname, 'build'),
filename: 'bundle.js'
//pulicPath:'build/'
},
module:{
rules:[
{
test:/\.css$/,
// css-loader只负责将css文件进行加载
// style-loader负责将样式添加到DOM中
// 使用多个loader时, 是从右向左
use:['style-loader','css-loader']
}
,{
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
},
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
//loader:'file-loader',
options: {
// 当加载的图片, 小于limit时, 会将图片编译成base64字符串形式.
// 当加载的图片, 大于limit时, 需要使用file-loader模块进行加载.
limit: 13000,
//esModule:false,
name:'[hash:10].[ext]'
//
// name: 'img/[name].[hash:8].[ext]'
},
}
]
}
// },
// {
// test:/\.html$/,
// loader:'html-loader'
// }
]
},
plugins:[
new HtmlWebpackPlugin({
template:'./index.html'
})
]
}
在前面我们说过,如果希望将ES6的语法转成ES5,那么就需要使用babel。
而在webpack中,我们直接使用babel对应的loader就可以了。
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
配置webpack.config.js
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
npm install vue --save (这里没有加-dev,加了-dev是开发时依赖但运行时不用依赖。然而我们的vue运行时需要依赖,所以就不加-dev了),然后为了学习,我的版本设置的与老师一样 npm i [email protected] --save
使用:
import Vue from 'vue'
原因:
解决:增加配置(module.exports里面)
resolve: {
// alias: 别名
extensions: ['.js', '.css', '.vue'],
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
如果我们希望将data中的数据显示在界面中,就必须是修改index.html 如果我们后面自定义了组件,也必须修改index.html来使用组件 但是html模板在之后的开发中,我并不希望手动的来频繁修改,是否可以做到呢?
定义template属性:
在前面的Vue实例中,我们定义了el属性,用于和index.html中的#app进行绑定,让Vue实例之后可以管理它其中的内容
这里,我们可以在index.html中将div元素中的{{message}}内容删掉,只保留一个基本的id为div的元素
我们可以在main.js中再定义一个template属性,代码如下:
new Vue({
el:'#app',
template:`
嘻嘻嘻开心{{message}}
`,
data:{
message:'苹妹妹'
}
})
el和template模板的关系是什么呢?
在我们之前的学习中,我们知道el用于指定Vue要管理的DOM,可以帮助解析其中的指令、事件监听等等。
而如果Vue实例中同时指定了template,那么template模板的内容会替换掉挂载的对应el的模板。
这样做有什么好处呢?
这样做之后我们就不需要在以后的开发中再次操作index.html,只需要在template中写入对应的标签即可
配置.vue模板
安装vue-loader和vue-template-compiler
npm install [email protected] vue-template-compiler --save-dev
报错了(我最开始的vue是2.5.21版本,与vue-template-compiler不一致),我在package.json里面更改,再npm i 重新安装,就成功了。
嘻嘻嘻,成功啦
代码展示:
main.js
import Vue from 'vue'
// 1.使用commonjs的模块化规范
const {add, mul} = require('./js/mathUtils.js')
require('./css/normal.css')
console.log(add(20, 30));
console.log(mul(20, 30));
// 2.使用ES6的模块化的规范
import {name, age, height} from "./js/info";
console.log(name);
console.log(age);
console.log(height);
// 4.依赖less文件
require('./css/special.less')
document.writeln('你好啊,小苹苹!
')
import App from './vue/App.vue'
new Vue({
el:'#app',
template:`
`,
components:{
App
}
})
App.vue
{{message}}
{{name}}
Cpp.vue
我是cpn的标题
{{name}}}
webpack.config.js
// const path = require('path')
const {resolve}=require('path')
const HtmlWebpackPlugin=require('html-webpack-plugin')
module.exports = {
entry: './src/main.js',
output: {
path: resolve(__dirname, 'build'),
filename: 'bundle.js'
//pulicPath:'build/'
},
module:{
rules:[
{
test:/\.css$/,
// css-loader只负责将css文件进行加载
// style-loader负责将样式添加到DOM中
// 使用多个loader时, 是从右向左
use:['style-loader','css-loader']
}
,{
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
},
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
//loader:'file-loader',
options: {
// 当加载的图片, 小于limit时, 会将图片编译成base64字符串形式.
// 当加载的图片, 大于limit时, 需要使用file-loader模块进行加载.
limit: 13000,
//esModule:false,
name:'[hash:10].[ext]'
//
// name: 'img/[name].[hash:8].[ext]'
},
}
]
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test:/\.vue$/,
use:['vue-loader']
}
// },
// {
// test:/\.html$/,
// loader:'html-loader'
// }
]
},
plugins:[
new HtmlWebpackPlugin({
template:'./index.html'
})
],
resolve: {
// alias: 别名
extensions: ['.js', '.css', '.vue'],
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
}
plugin是插件的意思,通常是用于对某个现有的架构进行扩展。 webpack中的插件,就是对webpack现有功能的各种扩展,比如打包优化,文件压缩等等
loader主要用于转换某些类型的模块,它是一个转换器。
plugin是插件,它是对webpack本身的扩展,是一个扩展器。
步骤一:通过npm安装需要使用的plugins(某些webpack已经内置的插件不需要安装)
步骤二:在webpack.config.js中的plugins中配置插件。
该插件名字叫BannerPlugin,属于webpack自带的插件。
我们需要将index.html文件打包到dist文件夹中,这个时候就可以使用HtmlWebpackPlugin插件
HtmlWebpackPlugin插件可以为我们做这些事情:
自动生成一个index.html文件(可以指定模板来生成)
将打包的js文件,自动通过script标签插入到body中
下载:npm install html-webpack-plugin --save-dev
我们使用一个第三方的插件uglifyjs-webpack-plugin,并且版本号指定1.1.1,和CLI2保持一致
下载:npm install [email protected] --save-dev
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
.......其余省略
plugins:[
new webpack.BannerPlugin('最终版权归zlppassion所有'),
new HtmlWebpackPlugin({
template:'./index.html'
}),
new UglifyjsWebpackPlugin()
]
webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。
npm install --save-dev [email protected]
这里的版本是与webpack3.6.0和cli2 相匹配的一个版本
devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:
contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./build
port:端口号
inline:页面实时刷新
historyApiFallback:在SPA页面中,依赖HTML5的history模式
package.json里面的配置,加了--open就可以自动跳转到浏览器显示了。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"dev":"webpack-dev-server --open"
},
webpack.config.js的配置
devServer: {
contentBase: './build',
inline: true
}
执行命令npm run dev即可。
base.config.js里面放共有的,dev.config.js里面放开发时用的,而prod.config.js放生产时用的。
安装:
npm install webpack-merge --save-dev
当三个js文件都写好后,之前的webpack.config.js就可以删掉了。但是运行前先记得配置package.json里面的scripts.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config ./build/prod.config.js",
"dev": "webpack-dev-server --open --config ./build/dev.config.js"
},
因为默认是执行webpack.config.js的
代码:
base.config.js
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, '../dist'),
filename: 'bundle.js',
// publicPath: 'dist/'
},
module: {
rules: [
{
test: /\.css$/,
// css-loader只负责将css文件进行加载
// style-loader负责将样式添加到DOM中
// 使用多个loader时, 是从右向左
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.less$/,
use: [{
loader: "style-loader", // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader", // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
// 当加载的图片, 小于limit时, 会将图片编译成base64字符串形式.
// 当加载的图片, 大于limit时, 需要使用file-loader模块进行加载.
limit: 13000,
name: 'img/[name].[hash:8].[ext]'
},
}
]
},
{
test: /\.js$/,
// exclude: 排除
// include: 包含
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve: {
// alias: 别名
extensions: ['.js', '.css', '.vue'],
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
plugins: [
new webpack.BannerPlugin('最终版权归aaa所有'),
new HtmlWebpackPlugin({
template: 'index.html'
})
]
}
dev.config.js
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')
module.exports = webpackMerge(baseConfig, {
devServer: {
contentBase: './dist',
inline: true
}
})
prod.config.js
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')
module.exports = webpackMerge(baseConfig, {
plugins: [
new UglifyjsWebpackPlugin()
]
})