rollup搭建项目
现在的项目基本都开始用rollup搭建的,很快要放弃webpack了。
初始化
npm init
接着按照步骤填入信息,生成package.json,默认入口为main.js,暂时写成main.js,后面会修改入口文件为编译后的文件
在根目录新建src文件夹,在src文件夹下新建main.ts文件:
export function hello () {
console.log('hello indeex')
}
配置rollup
安装typescript、rollup:
npm i -D typescript
npm i -S rollup
配置eslint
安装eslint:
npm i -D eslint
生成eslint配置文件(这个过程有点长😁):
./node_modules/.bin/eslint --init
提示需要:
Need to install the following packages:
@eslint/create-config
确认后根据需求选择不同配置,有三中配置:
? How would you like to use ESLint? …
To check syntax only
To check syntax and find problems
❯ To check syntax, find problems, and enforce code style
选择To check syntax, find problems, and enforce code style(检查语法格式、查找问题、统一代码风格),详细规则配置见eslint文档和tslint文档
接着有三种不同模式:
? What type of modules does your project use? …
❯ JavaScript modules (import/export)
CommonJS (require/exports)
None of these
选择JavaScript modules (import/export)
接着是库的选择:
? Which framework does your project use? …
React
Vue.js
❯ None of these
根据需求选择相应库,也可以不使用库,后期再配置,比如后期配置使用svelte库
接着选择编程语言:
? Does your project use TypeScript? › No / Yes
选择Yes。Yes使用Typescript,No使用Javascript(ECMA 262即ECMAScript)
接着选择运行环境:
? Where does your code run? … (Press <space> to select, <a> to toggle all, <i> to invert selection)
✔ Browser
✔ Node
选择Browser。也可以选择非浏览器环境
接着选择样式:
? How would you like to define a style for your project? …
Use a popular style guide
❯ Answer questions about your style
选择Answer questions about your style,由于是空项目,这里会少一个检测现有项目并自动生成的选项
接着选择格式化代码方式:
? What format do you want your config file to be in? …
❯ JavaScript
YAML
JSON
选择JavaScript
接着选择代码缩进方式:
? What style of indentation do you use? …
❯ Tabs
Spaces
选择Tabs
接着选择字符串单双引号:
? What quotes do you use for strings? …
Double
❯ Single
选择Single。依据团队或个人习惯选择。双引号要使用Shift+单引号 组合键,没有单引号按键方便,但双引号是很多团队的代码规范
接着是单纯的询问使用的操作系统:
? What line endings do you use? …
❯ Unix
Windows
选择Unix
结尾加不加英文分号:
? Do you require semicolons? › No / Yes
选择Yes
接着是单纯的询问使用的操作系统:
? What line endings do you use? …
❯ Unix
Windows
选择Unix。提示需要依赖:
The config that you've selected requires the following dependencies:
eslint-plugin-react@latest @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
接着是询问要不要安装:
? Would you like to install them now? › No / Yes
选择Yes
最后还要询问用什么安装:
? Which package manager do you want to use? …
❯ npm
yarn
pnpm
哪个安装的快用哪个。
选择后会显示要安装的依赖:
Installing eslint-plugin-react@latest, @typescript-eslint/eslint-plugin@latest, @typescript-eslint/parser@latest
安装完成后,会生成配置文件.eslintrc.js,并自动开始安装相应依赖,自动安装失败,就手动安装一遍上面提示的依赖
配置忽略文件
在根目录新建.eslintignore文件:
dist/**
node_modules/**
在根目录新建.gitignore文件:
/node_modules
/dist
# production
/build
# misc
.DS_Store
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env.local
.env.*.local
# typescript
*.tsbuildinfo
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
配置babel
安装依赖:
# 删除文件依赖
npm i -D rimraf
# typescript编译依赖
npm i -D rollup-plugin-typescript2
# rollup依赖
npm i -D @rollup/plugin-node-resolve @rollup/plugin-commonjs rollup rollup-plugin-terser
# babel依赖
npm i -D @babel/core @rollup/plugin-babel @babel/preset-env @babel/plugin-transform-runtime
@rollup/plugin-commonjs依赖为了让打包后的输出文件有commonjs、esm(ecmascript module)、umd三种模式
修改package.json:
"main": "./dist/index.js",//rollup.config.js中设置的commonjs模式打包出的文件
"module": "./dist/index.esm.js",
"umd": "./dist/index.umd.js",
"types": "./dist/types/index.d.ts",//类型声明文件入口
修改rollup.config.js文件:
/*
* @Author: indeex
* @Date: 2019-06-16 21:29:23
* @Email: indeex@qq.com
*/
import path from 'path'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import rollupTypescript from 'rollup-plugin-typescript2'
import babel from '@rollup/plugin-babel'
import { DEFAULT_EXTENSIONS } from '@babel/core'
import { terser } from 'rollup-plugin-terser'
import pkg from './package.json'
const env = process.env.NODE_ENV
const name = "RollupTypescript"
const config = {
input: path.resolve(__dirname, "src/main.ts"),
output: [
//commonjs
{
file: pkg.main,
format: 'cjs',
},
//esm
{
file: pkg.module,
format: 'es',
},
//umd
// {
// file: pkg.umd,
// format: 'umd'
// },
],
plugins: [
resolve(),//解析第三方依赖
commonjs(),//识别commonj和第三方依赖
rollupTypescript(),//rollup编译typescript
babel({
babelHelpers: 'runtime',//使用runtime编译库
exclude: 'node_modules/**',
extensions: [
...DEFAULT_EXTENSIONS,
'.ts',
],
}),
],
}
// 对生产环境进行代码压缩
if (env === 'production') {
config.plugins.push(terser({
compress: {
pure_getters: true,
unsafe: true,
unsafe_comps: true,
warnings: false,
},
}))
}
export default config
在根目录,新建tsconfig.json文件:
{
"compilerOptions":
{
/* 基础选项 */
"target": "esnext", /* 指定 ECMAScript 目标版本:'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "esnext", /* 输出的代码使用什么方式进行模块化: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": [ /* 指定引用的标准库 */
"esnext",
"dom",
"dom.iterable",
],
"allowJs": true, /* 允许编译 js 文件 */
"removeComments": true, /* 输出不包含注释 */
/* 严格类型检查选项 */ "strict": true, /* 启用所有严格类型检查选项 */
"noImplicitAny": true, /* 检查隐含 any 类型的表达式和声明 */
"strictNullChecks": false, /* 严格空检查. */
/* 额外检查 */
"noUnusedLocals": true, /* 检查无用的变量. */
/* Module Resolution Options */
"moduleResolution": "node", /* 指定模块查找策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6) */
"baseUrl": "./", /* 查找模块的基础目录 */
"paths": {
"@/*": [
"src/*"
]
}, /* 记录 baseUrl 的模块路径查找别名 */ "types": [], /* 类型声明文件 */
"allowSyntheticDefaultImports": true,
"jsx": "preserve"
},
"include": [
/* 指定编译处理的文件列表 */
"src/**/*",
"src/types.ts"
],
"exclude": ["node_modules", "config", "dist", "public"]
}
在根目录,新建tsconfig.types.json文件:
{
// 继承 tsconfig.json 中的通用配置
"extends": "./tsconfig.json",
"compilerOptions": {
"declaration": true, /* 生成相应的 '.d.ts' file. */
"declarationDir": "./dist/types", /* 类型声明文件输出目录 */
"emitDeclarationOnly": true, /* 只生成声明文件,不生成 js 文件*/
"rootDir": "./src", /* 指定输出文件目录(用于输出),用于控制输出目录结构 */
}
}
在根目录,新建babel.config.js文件:
module.exports = {
"presets": [
[
"@babel/preset-env",
{
/* Babel 会在 Rollup 有机会做处理之前,将我们的模块转成 CommonJS,导致 Rollup 的一些处理失败 */
"modules": false
}
]
],
"plugins": [
[
// 与 babelHelpers: 'runtime' 配合使用
"@babel/plugin-transform-runtime"
]
]
}
babel.config.js会影响整个项目中的代码,包含node_modules中的代码
babelrc 只会影响本项目中的代码,注意如果要使用.babelrc配置,请在src下创建.babelrc文件
修改package.json中scripts字段并增加files字段:
"scripts": {
"clean:dist": "rimraf dist",//清空dist打包目录
"build:types": "npm run clean:dist && tsc -b ./tsconfig.types.json",//编译ts类型声明文件
"build": "npm run build:types && rollup -c",
"test": "node test/test.js",
"pretest": "npm run build"//执行test命令时禁止该命令
},
"files": ["dist"],
在终端测试:
npm run build
会生成dist文件夹,文件夹内有index.js文件、index.esm.js文件、类型声明文件
test
在根目录新建test文件夹,在文件夹下新建test.js文件:
const { hello } = require('../dist/index.js')
hello()
在终端测试:
npm run test
会在终端打印hello indeex
postcss和预处理器
rollup-plugin-postcss支持Sass、Less和Stylus
# postcss
npm i -D postcss rollup-plugin-postcss
# sass
npm i -D node-sass
# or less
npm i -D less
# or stylus
npm i -D stylus
如果安装node-sass有问题,可以更换其他预处理器
修改rollup.config.js文件:
//...
import postcss from 'rollup-plugin-postcss'
import sass from 'node-sass'
//...
plugins: [
//...
postcss({
modules: true,//开启css modules,.module.css .module.sss .module.scss .module.sass .module.styl .module.stylus .module.less
extract: true,
minimize: productEnv,
extensions: ['css', 'scss', 'sass'],
process: processSass,
}),
],
css浏览器自动补全
npm i -D autoprefixer
修改rollup.config.js文件:
//...
import autoprefixer from 'autoprefixer'
//...
plugins: [
//...
postcss({
//...
plugins: [
autoprefixer(),
],
}),
],
修改package.json文件:
//...
"browserslist": [
"defaults",
"not ie < 8",
"last 2 versions",
"> 1%",
"iOS 7",
"last 3 iOS versions"
]
本地服务器
npm install -D rollup-plugin-serve
修改rollup.config.js文件:
//...
import serve from 'rollup-plugin-serve'
//...
plugins: [
//...
serve({
open: true,
contentBase: "public",
host: "localhost",
port: 9999,
}),
],
在根目录下新建public文件夹,在此文件夹下新建index.html文件,配置页面中的logo icon
运行npm run build会启动本地服务器并打开浏览器,并看到页面
开发环境和生产环境
在根目录下新建rollup.config.dev.js文件:
import serve from 'rollup-plugin-serve'
import config from './rollup.config'
const indexPath = 'public/index.html'
config.plugins = [
...config.plugins,
serve({
host: "localhost",
port: 9998,
onListening: (server) => {
const address = server.address()
const host = address.address === '::' ? 'localhost' : address.address
const protocol = server.https ? 'https' : 'http'
console.log(`Server listening at ${protocol}://${host}:${address.port}`)
}
}),
]
module.exports = config
在根目录下新建rollup.config.prod.js文件:
import config from './rollup.config'
process.env.NODE_ENV = 'production'
config.output.sourcemap = false
config.plugins = [...config.plugins]
module.exports = config
将所有的rollup.config开头的配置移动到根目录的config文件夹下,修改rollup.config.js:
//修改路径
import pkg from './../package.json'
//修改入口路径
const config = {
input: path.resolve( path.resolve(__dirname), '..', 'src/main.ts'),
}
修改.eslintrc.js文件:
module.exports = {
//...
'settings': {
'react': {
'version': 'detect'
}
}
};
修改package.json文件的scripts字段:
"scripts": {
"dev": "npm run lint && rollup -w -c ./config/rollup.config.dev.js",
"clean:dist": "rimraf dist",
"build:types": "npm run clean:dist && tsc -b ./tsconfig.types.json",
"build": "npm run build:types && npm run lint && rollup -c ./config/rollup.config.prod.js",
"test": "node test/test.js",
"pretest": "npm run build",
"lint": "eslint --fix --ext .ts,.js src"
},
代码混淆
npm i -D rollup-plugin-uglify
修改rollup.config.prod.js文件:
//...
import {uglify} from 'rollup-plugin-uglify'
//...
config.plugins = [...config.plugins, uglify({sourcemap: false})]
热更新
npm i -D rollup-plugin-livereload
修改rollup.config.dev.js文件:
//...
import livereload from 'rollup-plugin-livereload'
//...
config.plugins = [
//...
livereload(),
]
alias别名
npm i -D @rollup/plugin-alias
修改rollup.config.js文件:
//...
import alias from '@rollup/plugin-alias'
//...
plugins: [
//...
alias({
entries: [
{
find: "@",
replacement: path.resolve(path.resolve(__dirname), "..", "src"),
},
{
find: "src",
replacement: path.resolve(path.resolve(__dirname), "..", "src"),
},
],
customResolver,
}),
],
代码格式化
npm i -D prettier rollup-plugin-prettier
在根目录下新建.prettierrc.js文件:
module.exports = {
printWidth: 100,
singleQuote: true,
trailingComma: 'none',
bracketSpacing: true,
bracketSameLine: true,
tabWidth: 4,
arrowParens: "always",
}
修改rollup.config.js文件:
//...
import prettier from 'rollup-plugin-prettier'
const prettierConfig = path.resolve(path.resolve(__dirname), '..', '.prettierrc.js');
//...
plugins: [
//...
prettier(prettierConfig),
],
polyfill
由于babel无法转换所有新语法,如Map,需要使用babel-polyfill:
npm i -D core-js regenerator-runtime
修改babel.config.js文件:
module.exports = {
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",//按需加载polyfill
"corejs": {
"version": 3
},
}
]
],
//...
}
如果不需要框架基本完成了,可以直接使用html和编译的js和css文件
code enjoy! 🦖🦖🦖
作者:indeex
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。