前端现在流行“模块化开发”这样一个理念,例如:我们的Nodejs 模块化,vue 组件化都是这样一个思想。
模块化开发,依赖于ES6 里面的基础语法:export default和import…from
index.html:注意script 标签的type 属性值给定为"module"
注:在vscode 编辑器中测试时需要安装插件live server ,打开页面时选择“Open with Live Server”。
模块的理解
//my.js
let student={
username:"贺子航",
age:18
};
export default student;//或export default "某个值"
export var x=100,y=function(){alert("hello world!")};//或export {x,y}
为什么要使用模块化开发?
1, 形成一个封闭的空间:里面的变量是独立的,是“局部变量”;
2, 只加载一次,再需要用到时从内存上读取;
3, 项目的工程化。
require(module.exports /exports) 和 import(export default/export) 的区别:
1, require 是 AMD规范引入方式(node平台);import 是es6的一个语法标准
2, require是运行时调用,所以require理论上可以运用在代码的任何地方;import是编译时调用,所以必须放在文件开头(代码最外层)。
webpack 把所有的东西全部看成模块:js、css、图片、字体库等静态资源。
SPA:simple page application,单页面应用
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个*依赖关系图(dependency graph)*,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
webpack 是组件化开发的基础,只是一个打包工具,这个工具是nodejs写的。
在安装Webpack之前,本地环境需要支持Node.js。
由于npm安装速度慢,推荐使用淘宝镜像cnpm
使用cnpm安装Webpack
#创建项目目录
mkdir app
cd app//进入app文件夹
#初始化
npm init -y
或者cnpm i
#安装webpack
cnpm install webpack webpack-cli --save-dev
#全局安装
cnpm install webpack webpack-cli -g
查看webpack版本
webpack -v
webpack-cli -v
在app文件夹下创建一个src目录,并创建一个src/js/bar.js,填入以下代码:
console.log("webpack打包的第一个项目")
创建一个app/webpack.config.js文件,文件全名必须为"webpack.config.js",写入配置
const path=require("path");
module.exports={
entry:"./src/js/bar.js",
output:{
path:path.resolve(__dirname,"dist"),
filename:"bundle.js"
},
mode:"development"
}
在命令行输入webpack完成打包
在config配置文件中添加模式设置,mode: 'development或mode: 'production',解除警告,产品模式是为保证速度快放在指定目录下,他的包不会自动更新。开发模式是比较自由的,它保证开发灵活性,随便把它扔哪里 都会自动更新,这样会影响速度。一般地开发好的产品,都给客户用产品模式部署。一般采用开发者模式
module.exports = {
mode: 'production'
};//也可以在 CLI 参数中传递:
webpack --mode production
webpack --mode development
在webpack执行命令之后可以添加一些参数,这些参数都有自己的作用,下面是参数列表:
$ webpack src/js/main.js -o dist/js/bundle.js --mode development //命令行配置入口出口
$ webpack --config XXX.js //使用另一份配置文件(比如webpack.config2.js)来打包
$ webpack --watch //监听变动并自动打包
$ webpack --progress //显示进度条
$ webpack --color //添加颜色
在 CLI 参数中也可以配置入口/出口文件等,由于大型项目会填充多项配置,容易造成配置冗余,所以主流还是采用配置文件书写,下面介绍配置文件的主要配置项。
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
每个依赖项随即被处理,最后输出到称之为 bundles 的文件中。可以通过在 webpack 配置中配置 entry
属性,来指定一个入口起点(或多个入口起点)。默认值为 ./src
。
module.exports = {
entry: './path/to/my/entry/file.js'
};
output 属性告诉 webpack 在哪里输出path它所创建的 bundles,以及如何命名filename这些文件,默认值为 ./dist
。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个 output
字段,来配置这些处理过程:
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
};
在上面的示例中,通过 output.filename
和 output.path
属性,来告诉 webpack bundle 的名称,以及我们想要 bundle 生成(emit)到哪里。
上面导入的path 模块是一个 Node.js 核心模块,用于操作文件路径。
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
loader 能够 import
导入任何类型的模块(例如 .css
文件),这是 webpack 特有的功能,其他打包程序或任务执行器的可能并不支持。我们认为这种语言扩展是有很必要的,因为这可以使开发人员创建出更准确的依赖关系图。
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
path: './dist',
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{test: /\.txt$/, use: 'raw-loader' },
{test: /\.css$/, use: ['style-loader', 'css-loader']}
]
}
};
module.exports = config;
以上配置表示当webpack 编译器碰到在 require()
/import
语句中被解析为 '.txt' 的路径时,在对它打包之前,先使用 raw-loader
转换一下。
loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
想要使用一个插件,你只需要 require()
它,然后把它添加到 plugins
数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new
操作符来创建它的一个实例
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件
const config = {
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
补充:配置文件,入口和出口,多入口、多出口配置
//多入口配置
entry: {
myhome: path.resolve(__dirname, "src/home/index.js"),
myabout: path.resolve(__dirname, "src/about/index.js")
}
//多出口配置
output:{
//输出的路径,用了Node语法
path:path.resolve(__dirname,'dist'),
//输出的文件名称
filename:'[name].js'
}
考虑到用 CLI 这种方式来运行本地的 webpack 不是特别方便,我们可以设置一个快捷方式。在 package.json 添加一个 npm 脚本(npm script):
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
+ "build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.0.1",
"webpack-cli": "^2.0.9",
"lodash": "^4.17.5"
}
}
现在,可以使用 npm run build
命令,来替代我们之前使用的命令。
现在运行以下命令,然后看看你的脚本别名是否正常运行:
>npm run build
Hash: dabab1bac2b940c1462b
Version: webpack 4.0.1
Time: 323ms
Built at: 2018-2-26 22:50:25
Asset Size Chunks Chunk Names
bundle.js 69.6 KiB 0 [emitted] main
Entrypoint main = bundle.js
[1] (webpack)/buildin/module.js 519 bytes {0} [built]
[2] (webpack)/buildin/global.js 509 bytes {0} [built]
[3] ./src/index.js 256 bytes {0} [built]
+ 1 hidden module
WARNING in configuration(配置警告)
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.('mode' 选项还未设置。将 'mode' 选项设置为 'development' 或 'production',来启用环境默认值。)
例如:
1、在scripts中添加命令
"start": "webpack --config webpack.config.js"
2、执行 npm run start 就可以将项目进行打包
为了从 JavaScript 模块中 import
一个 CSS 文件,你需要在 module
配置中 安装并添加 style-loader 和 css-loader:
cnpm install --save-dev style-loader css-loader mini-css-extract-plugin
webpack.config.js
const path = require('path');
const MiniCssExtractPlugin=require("mini-css-extract-plugin")
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,//以标签href 属性的形式实现外联引入
// 'style-loader',//以