webpack构建项目
webpack入门(1)
源码戳这里
ps:每个案例对应相应的demo,例如“案例1”对应“demo1”
一、webpack基本功能及简单案例
安装webpack
$ npm i webpack -g基本功能
$ webpack -v 查看webpack版本号
$ webpack 最基本的启动webpack的方法
$ webpack -w 提供watch方法;实时进行打包更新
$ webpack -p 对打包后的文件进行压缩
$ webpack -d 提供source map,方便调式代码
$ webpack --display-error-details 显示更多报错信息
$ webpack --config webpack.config2.js 使用另一份配置文件webpack.config2.js来打包
$ webpack --progress 显示进度条
$ webpack --color 添加颜色
案例1
构建项目文件夹, 目录如下
[webpack]
|-- src
|-- index.js
|-- index.less
|-- index.html
|-- package.json
|-- webpack.config.js
webpack/src/index.html 内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script src='../build/app.js'></script>
</html>
webpack/src/index.less 内容如下
body {
background: yellow;
}
webpack/src/index.js 内容如下
console.log(123)
运行 $ npm init , 入下图所示
然后就看到webpack/package.json文件的内容, 如下
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
配置 webpack.config.js
webpack/webpack.config.js 文件的内容,如下
var webpack = require('webpack');
module.exports = {
entry: './src/index.js', // 入口文件地址
output: {
filename: './build/app.js' // 输出文件地址和名字
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: "style-loader!css-loader"
},
{
test: /\.less/, // less-loader
loaders: 'style-loader!css-loader!less-loader'
}
],
}
}
分析如下图
安装依赖
安装webpack依赖
$ npm i webpack --save-dev
$ npm i webpack@x.x.x --save-dev(安装指定版本的webpack)安装css依赖
$ npm i css-loader --save-dev
$ npm i style-loader --save-dev安装less依赖
$ npm i less --save-dev
$ npm i less-loader --save-dev安装es6依赖
$ npm i babel-loader --save-dev
$ npm i babel-preset-es2015 --save-dev
$ npm i babel-core --save-dev
这个时候再看webpack/package.json文件,就会发现多了一部分内容,如下图所示
运行 $ webpack , 会发现项目文件夹下多了一个文件 webpack/build/app.js , 如下图所示
打开在浏览器打开 webpack/src/index.html ,会看到如下图所示
这样我们已经有了一个简单的案例,在入口文件index.js里引入相关的依赖,然后通过webpack把他们打包好,并生成到build/app.js文件里。在index.html里只需要引入app.js文件,就能够看到背景色和console.log打印的值。
如下图所示
webpack/package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"start": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"css-loader": "^0.28.7",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"style-loader": "^0.19.0",
"webpack": "^3.8.1"
}
}
将webpack/build文件夹删除,运行$ npm run start,也能生成webpack/build/app.js
二、简单介绍下package.json中的devDependencies的版本号
以devDependencies中,webapck的版本号为例
devDependencies的版本号写法 安装依赖的版本 "webpack": "3.8.1" 等于3.8.1 "webpack": "~3.8.1" 3.8.x,不会安装3.9.x或者3.7.x "webpack": "^3.8.1" 3.x.x,不会安装4.x.x或者2.x.x "webpack": ">3.8.1" 大于3.8.1 "webpack": ">=3.8.1" 大于等于3.8.1 "webpack": "<=3.8.1" 小于等于3.8.1
三、 webpack-dev-server
轻量级的服务器,可以修改代码后,在页面上看到修改完的效果,详细介绍戳这里
安装依赖
$ npm i webpack-dev-server -g
$ npm i webpack-dev-server --save-dev
案例2
ps:每个案例都是基于前一个案例的内容改造,没有提到的文件和前一个案例内容一样
运行 $ webpack-dev-server , 如下图
在浏览器打开连接 http://localhost:8080/src/ ,就能看到案例一的效果了
webpack/src/index.js
import './index.less';
const fn = () => {
document.write('hi!')
}
fn();
这个时候在页面能够实时更新,如下图所示
改造 webpack/package.json
webpack/package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"start": "webpack-dev-server",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"css-loader": "^0.28.7",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.3"
}
}
可选的参数
- --content-base: 设定webpack-dev-server的director根目录。如果不进行设定的话,默认是在当前目录下。
- --quiet: 控制台中不输出打包的信息,开发中一般设置为false,进行 打印,这样查看错误比较方面
- --no-info: 不显示任何信息
- --colors: 对信息进行颜色输出
- --no-colors: 对信息不进行颜色输出
- --compress: 开启gzip压缩
- --host <hostname/ip>: 设置ip
- --port : 设置端口号,默认是:8080
- --inline: webpack-dev-server会在你的webpack.config.js的入口配置文件中再添加一个入口,
- --hot: 开发热替换
- --open: 启动命令,自动打开浏览器
- --history-api-fallback: 查看历史url
- 更多参数戳这里
下面以“--port”举例
webpack/package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"start": "webpack-dev-server --port 7777",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"css-loader": "^0.28.7",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.3"
}
}
运行 $ npm run start
浏览器打开页面 http://localhost:7777/src/ ,即可看效果
webpack-dev-server后写多个参数:webpack-dev-server --hot --inline
四、output和entry
entry:入口文件,简单说就是要打包的文件。
output: 出口文件,简单说就是打包生成的文件。
entry有三种类型的值:字符串、数组、对象。案例一和案例二都是字符串的方式,下面来看下数组(案例三)和对象(案例四)的写法
案例3 --- entry值为数组的写法,多个入口对一个出口
新增文件 webpack/src/main.js,如下图
webpack/src/main.js
console.log('123')
webpack/webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: ['./src/index.js', './src/main.js'], // 入口文件地址
output: {
filename: './build/app.js' // 输出文件地址和名字
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: "style-loader!css-loader"
},
{
test: /\.less/, // less-loader
loaders: 'style-loader!css-loader!less-loader'
}
],
}
}
运行 $ npm run build,index.js和main.js两个文件最后生成一个webpack/build/app.js文件
运行 $ npm run start,打开 http://localhost:7777/src/ ,可以看到两个文件里的代码都生效了,如下图所示
案例4 --- entry值为对象的写法,多个入口对多个出口
webpack/webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: { // 入口文件地址
app: './src/index.js',
main: './src/main.js'
},
output: { // 输出文件地址和名字
filename: './build/[name].js'
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: "style-loader!css-loader"
},
{
test: /\.less/, // less-loader
loaders: 'style-loader!css-loader!less-loader'
}
],
}
}
webpack/src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script src='../build/app.js'></script>
<script src='../build/main.js'></script>
</html>
运行 $ npm run build,会生成webpack/build/app.js和webpack/build/main.js
将main.js也在index.html里引入一下,就能看见和案例三一样的效果
案例5 --- output的path和publicPath
webpack/package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"start": "webpack-dev-server --content-base --inline --hot --port 7777",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"css-loader": "^0.28.7",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.3"
}
}
webpack-dev-server的配置参数,可以去 案例2 的 可选的参数 里去找
webpack/webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: { // 入口文件地址
app: './src/index.js',
main: './src/main.js'
},
output: { // 出口文件
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js', // 文件名,name即为entry的key
publicPath: '/build' // 命令行模式下,一定要配置output.publicPath来指定编译后的包(bundle)的访问位置
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: "style-loader!css-loader"
},
{
test: /\.less/, // less-loader
loaders: 'style-loader!css-loader!less-loader'
}
],
}
}
__dirname:是一个全局变量,指当前执行脚本所在的目录
path和publicPath的区别:戳这里
运行 $ npm run build 和 $ npm run start (打开 http://localhost:7777/src/ ) 的效果和案例四一样
[name]不一定一定要是文件名,也可以是路径:
filename: '[name]/min.js'
可以自己运行下 $ webpack , 看下生成的文件,这里就不贴图展示了
output里filename有三个值:
· [name]是文件名字是entry的键值。
· [hash]是md5加密的值。
· [chunkhash]可以作为版本号使用。
五、html单独打包
安装依赖
$ npm install html-webpack-plugin --save-dev
可选的配置:
- title : 用于生成的HTML文件的标题。
- filename : 用于生成的HTML文件的名称,默认是index.html。也可以指定打包的目录,下面案例7中有介绍。
- template : 模板的路径。支持加载器,例如 html!./index.html。模板类型可以是html,jade,ejs,hbs等,注意要安装对应的loader
- inject : 注入选项,有四个值
- true(默认,script标签位于html文件的 body 底部)
- ‘head’(script 标签位于 head 标签内)
- ‘body’(同 true)
- false(不插入生成的 js 文件,只是单纯的生成一个 html 文件
- favicon : 给定的图标路径,可将其添加到输出html中。
- minify : 值为对象或者false,对 html 文件进行压缩,false是默认选项,不压缩。html-minifier详细文档戳这里。
- hash : true | false。如果是true,会给所有包含的script和css添加一个唯一的webpack编译hash值,类似于我们常用的时间戳。这对于缓存清除非常有用。
- cache : true(默认) | false 。是否需要缓存,如果传入true,只有在文件变化时才发送(emit)文件。
- showErrors : true | false 。如果传入true(默认),错误信息将写入html页面。
- chunks : 主要是针对多入口(entry)文件,默认会在生成的 html 文件中引用所有的 js 文件,也可以指定引入哪些js。
- excludeChunks : 和chunks刚好相反,指定不需要引入的js。
- chunksSortMode : 决定了 script 标签的引用顺序。有四个值
- ‘auto’,默认,内置的排序方式
- ‘none’,不排序
- ‘dependency’,按照不同文件的依赖关系来排序
- {function},可以指定具体排序规则
- xhtml : 布尔值
- false,默认
- true,兼容 xhtml 的模式引用文件
案例6 --- html-webpack-plugin的基本用法
webpack/package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"start": "webpack-dev-server --content-base build --inline --hot --port 7777 ",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"css-loader": "^0.28.7",
"html-webpack-plugin": "^2.30.1",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.3"
}
}
webpack-dev-server --content-base
设定webpack-dev-server的director根目录。如果不进行设定的话,默认是在当前目录下。
webpack-dev-server --content-base build
将build目录作为根目录。有一点需要注意的是,webpack-dev-server生成的包并没有放在你的真实目录中,而是放在了内存中。
webpack/webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: { // 入口文件地址
app: './src/index.js',
main: './src/main.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: "style-loader!css-loader"
},
{
test: /\.less/, // less-loader
loaders: 'style-loader!css-loader!less-loader'
}
],
},
plugins: [new HtmlWebpackPlugin()]
}
运行 $ npm run build ,会发现html被单独打包出来了webpack/build/index.html,如下图所示
运行 $ npm run start,打开 http://localhost:7777/ ,就能看到效果。因为我们默认打包后生成的html名就是index(主页面文件),所以这里相当于是打开了 http://localhost:7777/index.html
案例7 --- html-webpack-plugin的title和filename
webpack/webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: { // 入口文件地址
app: './src/index.js',
main: './src/main.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: "style-loader!css-loader"
},
{
test: /\.less/, // less-loader
loaders: 'style-loader!css-loader!less-loader'
}
],
},
plugins: [new HtmlWebpackPlugin({
title: 'demo',
filename: 'demo.html'
})]
}
filename是设置打包好的html文件名,title是设置html的标题。
运行 $ npm run build, 会将html打包webpack/build/demo.html,且页面标题为demo,如下图所示
运行 $ npm run start,打开 http://localhost:7777/demo.html 看页面效果
filename其他写法:(下面介绍两种,大家自己试一下)
- filename: './dist/demo.html'。 则html会被打包成webpack/build/dist/demo.html
- filename: __dirname + '/dist/demo.html'。 则html会被打包到webpack/dist/demo.html
案例8 --- html-webpack-plugin的template和chunks,生成多个html
新建文件 webpack/src/main.html,如下图所示
webpack/src/main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
</body>
</html>
webpack/src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
</body>
</html>
webpack/webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: { // 入口文件地址
app: './src/index.js',
main: './src/main.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: "style-loader!css-loader"
},
{
test: /\.less/, // less-loader
loaders: 'style-loader!css-loader!less-loader'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'demo.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['app'] // 需要引入的js
}),
new HtmlWebpackPlugin({
filename: 'main.html',
template: './src/main.html',
chunks: ['main']
})
]
}
运行 $ npm run build,生成的文件如下所示
webpack/src/index.html打包生成webpack/build/demo.html,并且引入的js是app.js。 webpack/src/main.html打包生成的是webpack/build/main.html,js引入的是main.js。
template:需要打包的html的文件路径
chunks:是一个数组,里面的值对应entry里的key,可以写多个,例如 chunks: ['app','main']
运行 $ npm run start, 分别打开 http://localhost:7777/main.html 和 http://localhost:7777/demo.html 可以看到页面效果
六、css单独打包
安装依赖 $ npm install extract-text-webpack-plugin --save-dev
new ExtractTextPlugin() 和 ExtractTextPlugin.extract() 详细介绍戳这里
- ExtractTextPlugin.extract(),有三个参数:
- 第一个参数是可选参数,传入一个loader,当css样式没有被抽取的时候可以使用该loader;
- 第二个参数则是用于编译解析的css文件loader,很明显这个是必须传入的,就像上述例子的css-loader;
- 第三个参数是一些额外的备选项,貌似目前只有传入publicPath,用于当前loader的路径。
- new ExtractTextPlugin([id: string], filename: string, [options])
- [id: string]:该插件实例的唯一标志,一般是不会传的,其自己会生成
- filename: 文件名,包含[name]、[id]、[contenthash]
- [name]:将会和entry中的chunk的名字一致
- [id]:将会和entry中的chunk的id一致
- [contenthash]:根据内容生成hash值
- options
- allchunk: 是否将所有额外的chunk都压缩成一个文件
- disable:禁止使用插件
案例9
新建文件webpack/src/main.css
webpack/src/main.css
body {
background: red;
}
webpack/src/main.js
import './main.css';
console.log('123')
webpack/webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: { // 入口文件地址
app: './src/index.js',
main: './src/main.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract(['css-loader'])
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract([ 'css-loader', 'less-loader' ])
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'demo.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['app'] // 需要引入的js
}),
new HtmlWebpackPlugin({
filename: 'main.html',
template: './src/main.html',
chunks: ['main']
}),
new ExtractTextPlugin("[name].css")
]
}
这里写了css和less两种文件的打包,并生成对应的名字
运行 $ npm run build,效果如下
在index.js里引入的index.less,最后生成的app.css,并且在index.html中引用了。在main.js里引入的main.css,打包后生成main.css,并且在main.html中引用。
运行 $ npm run start, 分别打开 http://localhost:7777/main.html 和 http://localhost:7777/demo.html 可以看到页面效果。
这个时候会发现,如果修改js页面还是会自动刷新,如果修改css或者less,页面需要手动刷新才会看到最新的效果
七、图片的处理
安装依赖
$ npm i url-loader --save-dev
$ npm i file-loader --save-dev
案例10
新增 webpack/src/images/Ahri.jpg
新增 webpack/src/images/Minions.jpg
webpack/src/index.less
body {
height: 500px;
background: url('./images/Ahri.jpg') no-repeat center;
}
webpack/src/main.css
body {
background: url('./images/Minions.jpg') no-repeat;
}
webpack/webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: { // 入口文件地址
app: './src/index.js',
main: './src/main.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract(['css-loader'])
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract([ 'css-loader', 'less-loader' ])
},
{
test: /\.(png|jpg)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'demo.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['app'] // 需要引入的js
}),
new HtmlWebpackPlugin({
filename: 'main.html',
template: './src/main.html',
chunks: ['main']
}),
new ExtractTextPlugin({
filename: '[name].css'
})
]
}
运行 $ npm run start
打开 http://localhost:7777/demo.html ,效果如下
打开 http://localhost:7777/main.html ,效果如下
运行 $ npm run build,如下所示
分析如下
- 除了png和jpg外,还可以添加gif等,以“|”分隔。
- limit=8192,图片小于8192字节时以,转为base64引入,大于8192字节时,调用file-loader打包生成文件
- name=images/[hash:8].[name].[ext],“ images/ ”指定图片打包到文件夹webpack/build/images,“ [hash:8] ”指8位 hash 值
可以自己尝试下这种打包出来的结果:
{
test: /\.(png|jpg)$/, // img-loader
loader: 'url-loader?limit=8192'
}
效果如下
八、引入jq
npm i jquery --save-dev
案例11
webpack/src/index.js
import './index.less';
import $ from 'jquery';
$('body').prepend('hehe');
这样运行 $ npm run build,jquery被打包到app.js里了
九、CommonsChunkPlugin 打包公共文件
new webpack.optimize.CommonsChunkPlugin({
name: xx, // 对应entry的key
filename: xx, // 输出的文件名,如果不写这个则以name为输出的文件名
chunks: xx // 只有在这个文件中引入的模块才能被打包
minChunks: xx, // 符合引用次数的则被打包
})
案例12 --- 单一入口,分文件输出
webpack/webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: { // 入口文件地址
app: './src/index.js',
// main: './src/main.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract(['css-loader'])
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract([ 'css-loader', 'less-loader' ])
},
{
test: /\.(png|jpg)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'demo.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['app', 'chunk'] // 需要引入的js
}),
// new HtmlWebpackPlugin({
// filename: 'main.html',
// template: './src/main.html',
// chunks: ['main']
// }),
new ExtractTextPlugin({
filename: '[name].css'
}),
new webpack.optimize.CommonsChunkPlugin("chunk")
]
}
$ npm run build, 打包出来的结果如下:
这里注意,chunk.js一定要在app.js之前引入
案例13 --- 多入口,分文件输出,jquery单独打包
webpack/webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: { // 入口文件地址
app: './src/index.js',
jquery: [ "jquery" ]
// main: './src/main.js'
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract(['css-loader'])
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract([ 'css-loader', 'less-loader' ])
},
{
test: /\.(png|jpg)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'demo.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['app', 'jquery'] // 需要引入的js
}),
// new HtmlWebpackPlugin({
// filename: 'main.html',
// template: './src/main.html',
// chunks: ['main']
// }),
new ExtractTextPlugin({
filename: '[name].css'
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'jquery'
})
]
}
运行 $ npm run build, 效果如下
通过webpack.optimize.CommonsChunkPlugin,将jquery单独打包到jquery.js中。如果不写这部分,app.js中也会被打包入jquery,大家可以自己尝试下。
案例14
webpack/webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: { // 入口文件地址
app: './src/index.js',
main: './src/main.js',
jquery: [ "jquery" ]
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract(['css-loader'])
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract([ 'css-loader', 'less-loader' ])
},
{
test: /\.(png|jpg)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [ // 插件
new HtmlWebpackPlugin({
filename: 'demo.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['app', 'jquery'] // 需要引入的js
}),
new HtmlWebpackPlugin({
filename: 'main.html',
template: './src/main.html',
chunks: ['main']
}),
new ExtractTextPlugin({
filename: '[name].css'
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'jquery',
chunks: ['app'] // 在app.js中引用的才被打包
})
]
}
$ npm run build, main.js和app.js中均为打包入jquery,jquery被单独打包,并且仅在demo.html中引用。
十、js压缩
这里介绍两种方式大家自己运行 $ npm run build 试试,对比下压缩前后的效果
- new webpack.optimize.UglifyJsPlugin()
webpack/webpack.config.js的plugins添加如下
module.exports = {
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]
}
- webpack -p
webpack/package.json的scripts修改如下
"scripts": {
"build": "webpack -p",
},
十一、自动添加css前缀 postcss-loader
类似下面这种需要添加浏览器前缀等兼容的情况,每次自己写太麻烦,可以用postcss-loader帮助我们完成这些功能
display: -webkit-box;
display: -ms-flexbox;
display: flex;
这里综合上面所讲的内容,从头写一个新的demo(简单的留言板效果), 效果如下
demo涉及到上面没有讲过的内容,如下:
- atpl-loader,写法戳这里
案例15
新建项目文件夹 webpackDemo,文件目录如下
运行 $ npm init。
安装以下依赖 :
babel-core
babel-loader
babel-preset-es2015
css-loader
extract-text-webpack-plugin
file-loader
html-webpack-plugin
jquery
less
less-loader
style-loader
url-loader
webpack
webpack-dev-server
webpackDemo/src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpackDemo</title>
</head>
<body>
<div class="wrapper"></div>
</body>
</html>
webpackDemo/src/css/reset.less
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
input, button {
outline:none;
}
webpackDemo/src/css/index.less
@import 'reset.less';
.wrapper {
margin: 50px auto;
border: 1px solid #000;
width: 400px;
height: 500px;
background: lightpink;
}
webpackDemo/src/index.js
import '../src/css/index.less';
import $ from 'jquery';
$('.wrapper').append('您好');
webpackDemo/package.json
{
"name": "webpackdemo",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"start": "webpack-dev-server --content-base build --inline --hot",
"build": "webpack -p",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"css-loader": "^0.28.7",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"html-webpack-plugin": "^2.30.1",
"jquery": "^3.2.1",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"style-loader": "^0.19.0",
"url-loader": "^0.6.2",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.9.5"
}
}
webpackDemo/webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: { // 入口文件地址
index: './src/index.js',
vendor: [ "jquery" ]
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader
loader: ExtractTextPlugin.extract(['css-loader'])
},
{
test: /\.less/, // less-loader
loaders: ExtractTextPlugin.extract([ 'css-loader', 'less-loader' ])
},
{
test: /\.(png|jpg)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index', 'vendor'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({
filename: '[name].css'
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor' // 对应entry的key
})
]
}
运行 $ npm run start, 打开 http://localhost:8080/ ,效果如下:
下面写banner(输入框和发送按钮)部分,先写一个简单的js
新建 webpackDemo/src/js/banner.js
webpackDemo/src/js/banner.js
export default function ($wrapper) {
$wrapper.append('banner');
}
webpackDemo/src/index.js
import '../src/css/index.less';
import $ from 'jquery';
import bannerRender from '../src/js/banner';
const $wrapper = $('.wrapper');
const init = () => {
bannerRender($wrapper);
}
init();
效果如下:
下面写banner部分的html部分和css部分
安装依赖 $ npm i atpl-loader postcss-loader --save-dev
新建
webpackDemo/src/tpl/banner.atpl
webpackDemo/src/css/banner.less
webpackDemo/postcss.config.js
webpackDemo/postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
}
webpackDemo/webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: { // 入口文件地址
index: './src/index.js',
vendor: [ "jquery" ]
},
output: { // 出口
path: __dirname + "/build", // 打包后的文件存放路径
filename: '[name].js' // 文件名,name即为entry的key
},
module: {
loaders: [
{
test: /\.js$/, // js-loader
loader: 'babel-loader?presets=es2015'
},
{
test: /\.css$/, // css-loader postcss-loader
loader: ExtractTextPlugin.extract('css-loader!postcss-loader')
},
{
test: /\.less/, // less-loader postcss-loader
loaders: ExtractTextPlugin.extract('css-loader!less-loader!postcss-loader')
},
{
test: /\.(png|jpg)$/, // img-loader
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
},
{
test: /\.atpl?$/, // atpl
loader: 'atpl-loader',
}
],
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的的html文件名
template: './src/index.html', // 被打包的html路径
chunks: ['index', 'vendor'] // 需要引入的js,对应entry的key
}),
new ExtractTextPlugin({
filename: '[name].css'
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor' // 对应entry的key
})
]
}
webpackDemo/src/tpl/banner.atpl
<div class="banner-wrap">
<input class="ipt" placeholder="在这里输入留言内容" />
<button class="btn">发送</button>
</div>
webpackDemo/src/css/banner.less
.banner-wrap {
height: 50px;
background: #fff;
display: flex;
.ipt {
flex: 1;
border: 0;
padding: 0 10px;
box-sizing: border-box;
font-size: 16px;
}
.btn {
border: 0;
width: 50px;
border-radius: 0;
color: #fff;
font-size: 16px;
background: #666;
}
}
webpackDemo/src/js/banner.js
import '../css/banner.less';
import bannerTpl from '../tpl/banner.atpl';
export default function ($wrapper) {
$wrapper.append(bannerTpl({}));
}
运行 $ npm run start , 打开 http://localhost:8080/index.html , 效果如下
下面写留言区域的部分
新建
webpackDemo/src/tpl/message.atpl
webpackDemo/src/css/message.less
webpackDemo/src/js/message.js
webpackDemo/src/tpl/message.atpl
<ul class="message-wrap">
<li>大家好!大家好!大家好!大家好!大家好!大家好!大家好!大家好!大家好!大家好!大家好!大家好!</li>
<li>留言6666666</li>
<li>留言555555</li>
<li>留言44444444</li>
<li>留言3333333</li>
<li>留言222222222</li>
<li>留言11111111</li>
</ul>
webpackDemo/src/css/message.less
.message-wrap {
padding: 25px;
height: 400px;
overflow-y: auto;
overflow-x: hidden;
li {
border-bottom: 1px dashed lightcoral;
padding: 10px 0;
line-height: 1.5;
}
}
webpackDemo/src/js/message.js
import '../css/message.less';
import messageTpl from '../tpl/message.atpl';
export default function ($wrapper) {
$wrapper.append(messageTpl({}));
}
webpackDemo/src/index.js
import '../src/css/index.less';
import $ from 'jquery';
import bannerRender from '../src/js/banner';
import messageRender from '../src/js/message';
const $wrapper = $('.wrapper');
const init = () => {
bannerRender($wrapper); // 引入banner部分
messageRender($wrapper); // 引入message部分
}
init();
运行 $ npm run start , 打开 http://localhost:8080/index.html , 效果如下
接下来写留言功能
webpackDemo/src/js/banner.js
import '../css/banner.less';
import bannerTpl from '../tpl/banner.atpl';
// html
const render = ($wrapper) => {
$wrapper.append(bannerTpl({}));
}
// 事件
const bindEvents = ($wrapper) => {
// 点击发送按钮发送输入框内容
$wrapper.on('click', '.btn', () => {
const $ipt = $wrapper.find('.ipt');
const $messageWrap = $wrapper.find('.message-wrap');
const val = $ipt.val();
// 当input有内容的时候才允许发送
if ($ipt.length && val.length) {
$messageWrap.prepend(`<li>${val}</li>`);
// 发送完后清空input的val
$ipt.val('');
}
})
}
export default function ($wrapper) {
render($wrapper);
bindEvents($wrapper);
}
运行 $ npm run start , 打开 http://localhost:8080/index.html,就能看到如下效果了
webpack构建项目的更多相关文章
- Vue2+VueRouter2+webpack 构建项目实战(三):配置路由,运行页面
制作.vue模板文件 通过前面的两篇博文的学习,我们已经建立好了一个项目.问题是,我们还没有开始制作页面.下面,我们要来做页面了. 我们还是利用 http://cnodejs.org/api 这里公开 ...
- Vue2+VueRouter2+webpack 构建项目实战(二):目录以及文件结构
通过上一篇博文<Vue2+VueRouter2+webpack 构建项目实战(一):准备工作>,我们已经新建好了一个基于vue+webpack的项目.本篇文章详细介绍下项目的结构. 项目目 ...
- Vue2+VueRouter2+webpack 构建项目实战(四)接通api,先渲染个列表
Vue2+VueRouter2+webpack 构建项目实战(四)接通api,先渲染个列表: Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(一)基础知识概述
- Vue2+VueRouter2+webpack 构建项目实战(一):准备工作
环境准备 首先,要开始工作之前,还是需要把环境搭建好.需要的环境是nodejs+npm,当然现在安装node都自带了npm. 在终端下面输入命令node -v会有版本号出来.就说明安装成功了.输入np ...
- Vue2+VueRouter2+webpack 构建项目实战(五):配置子路由
前言 通过前面几章的实战,我们已经顺利的构建项目,并且从API接口获取到数据并且渲染出来了.制作更多的页面,更复杂的应用,就是各位自己根据自己的项目去调整的事情了. 本章讲一下如何配置子路由,因为我们 ...
- webpack 构建项目入门
参考http://www.cnblogs.com/eyunhua/p/6398885.html ---------------------------------------------------- ...
- vue+webpack构建项目
概述 -- 项目中会用到的插件 vue-router vue-resource 打包工具 webpack 依赖环境 node.js start 安装vue开发的模板 # 全局安装 vue-cli $ ...
- Vue2+VueRouter2+webpack 构建项目实战(四):接通api,渲染列表
通过前面几篇教程,我们已经顺利搭建起来了,并且已经组建好路由了.本章节,我们需要做一个列表页面,然后利用获取 http://cnodejs.org/api 的公开API,渲染出来. 我们打开src/p ...
- webpack构建项目连接本机IP仍无法访问问题
通过连接IP地址,确定连接成功后仍无法访问本机运行项目,需要对项目配置进行修改,有两种情况: 第一种是在config/index.js,把module.exports={}中找到 host:'loca ...
随机推荐
- session失效问题
具体设置很简单,方法有三种: ()在主页面或者公共页面中加入:session.setMaxInactiveInterval();参数600单位是秒,即在没有10分钟活动后,session将失效. 这里 ...
- 数据帧CRC32校验算法实现
本文设计思想采用明德扬至简设计法.由于本人项目需要进行光纤数据传输,为了保证通信质量要对数据进行校验.在校验算法中,最简单最成熟的非CRC校验莫属了. 得出一个数的CRC校验码还是比较简单的: 选定一 ...
- 使用angular4和asp.net core 2 web api做个练习项目(二), 这部分都是angular
上一篇: http://www.cnblogs.com/cgzl/p/7755801.html 完成client.service.ts: import { Injectable } from '@an ...
- vim基本命令(转载自网络)
来源于<Unix初级教程(第四版)>. 命令模式切换到文本输入模式: 键 功能 i 在光标左侧输入文本 I 在当前行的行首输入文本 a 在光标右侧输入文本 A 在当前行的行尾输入文本 o ...
- Luck and Love(二维线段树)
Luck and Love Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- Stars(二维树状数组)
Stars Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/65536 K (Java/Others) Total Submiss ...
- 浅谈postgresql的GIN索引(通用倒排索引)
1.倒排索引原理 倒排索引来源于搜索引擎的技术,可以说是搜索引擎的基石.正是有了倒排索引技术,搜索引擎才能有效率的进行数据库查找.删除等操作.在详细说明倒排索引之前,我们说一下与之相关的正排索引并与之 ...
- JS中的this的应用总结
简述this的用法 "this是由被调用的方式确定"这个事实,使得this可以被改变,从而为函数增加了动态性,可变性,使得变成更加灵活.目前因为工作经验有限,暂时总结一下五种情况下 ...
- IE下 GIF不动失效的奇葩问题
IE下(IE6~IE9都有该问题),对页面进行了某些操作之后,页面上的GIF动画就停留在某一帧不动了~~~ !! 我大IE 就是这么奇葩. 搜索了一下,搞了好久总算搞定. 下面说下目前了解的所有的可能 ...
- 删除“自豪的采用wordpress”
网上的都是老一套了,方法不对. 听我的~ 先进入wordpress的安装目录,比如我的是:cd /www/wwwroot/www.yangnan.tk然后再进入,我的主题是twentyseventee ...