├── .editorconfig
├── .gitattributes
├── .gitignore
├── .travis.yml
├── README.md
├── example
├── .babelrc
├── .browserslistrc
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .lintstagedrc.json
├── .prettierrc.js
├── .vscode
│ └── setting.json
├── README.md
├── package-lock.json
├── package.json
├── postcss.config.js
├── project.config.json
├── src
│ ├── app.mina
│ ├── common.wxss
│ ├── components
│ │ ├── bar.mina
│ │ ├── circular.mina
│ │ ├── classical.js
│ │ ├── classical.json
│ │ ├── classical.wxml
│ │ └── foobar.mina
│ ├── images
│ │ ├── logo.png
│ │ └── tabs
│ │ │ ├── bell-active.png
│ │ │ ├── bell.png
│ │ │ ├── home-active.png
│ │ │ └── home.png
│ ├── packages
│ │ └── a
│ │ │ └── pages
│ │ │ └── home.mina
│ ├── pages
│ │ ├── home.mina
│ │ └── message.mina
│ ├── template
│ │ └── greeting.wxml
│ ├── utils
│ │ └── dependency.js
│ └── wxs
│ │ ├── datetime
│ │ └── now.wxs
│ │ ├── greeting.wxs
│ │ └── string
│ │ └── padding.wxs
└── webpack.config.js
├── lerna.json
├── package-lock.json
├── package.json
└── packages
├── mina-entry-webpack-plugin
├── .gitignore
├── .lintstagedrc.json
├── .prettierrc.js
├── LICENSE
├── README.md
├── package-lock.json
├── package.json
├── src
│ ├── config-readers
│ │ ├── classical.ts
│ │ └── mina.ts
│ ├── helpers
│ │ ├── entry.ts
│ │ └── index.ts
│ ├── index.ts
│ ├── interfaces
│ │ └── config-reader.ts
│ └── loaders
│ │ └── virtual-mina-loader.ts
├── test
│ └── helpers
│ │ └── entry.test.ts
└── tsconfig.json
├── mina-loader
├── .gitignore
├── .lintstagedrc.json
├── .prettierrc.js
├── LICENSE
├── README.md
├── package-lock.json
├── package.json
├── src
│ ├── constants.ts
│ ├── deps.d.ts
│ ├── helpers.ts
│ ├── index.ts
│ └── loaders
│ │ ├── mina-json.ts
│ │ ├── mina.ts
│ │ ├── parser.ts
│ │ ├── selector.ts
│ │ └── wxss-url.ts
├── test
│ ├── basic.js
│ ├── enforce-relative-path.js
│ ├── extensions.js
│ ├── fixtures
│ │ ├── basic
│ │ │ ├── app.mina
│ │ │ ├── cloud-url.mina
│ │ │ ├── dependency.a.js
│ │ │ ├── dependency.b.js
│ │ │ ├── empty.mina
│ │ │ ├── logo.png
│ │ │ ├── logo.png.txt
│ │ │ └── page.mina
│ │ ├── enforce-relative-path
│ │ │ └── page.mina
│ │ ├── entry
│ │ │ ├── app-basic.mina
│ │ │ ├── app-custom-extensions.mina
│ │ │ ├── app-inline-loaders.mina
│ │ │ ├── app-non-extname.mina
│ │ │ ├── app-not-existed-file.mina
│ │ │ ├── app-symbolic.mina
│ │ │ ├── app-unknown-file-type.mina
│ │ │ ├── app-virtual-extname.mina
│ │ │ ├── component-a.mina
│ │ │ ├── component-b.json
│ │ │ ├── component-c.mina
│ │ │ ├── hi.js
│ │ │ ├── logo.png
│ │ │ ├── page-a.mina
│ │ │ ├── page-b.mina
│ │ │ ├── page-c.js
│ │ │ ├── page-c.json
│ │ │ ├── page-d.wxml
│ │ │ ├── page-e.json
│ │ │ ├── page-f.wxss
│ │ │ ├── page-g.yaml
│ │ │ ├── page-h.ttml
│ │ │ ├── page-i.js
│ │ │ ├── page-i.ttml
│ │ │ ├── symbolic-a.mina
│ │ │ └── symbolic-b.mina
│ │ ├── extra-resources
│ │ │ ├── github.mina
│ │ │ ├── github.png
│ │ │ ├── subdir
│ │ │ │ └── symbolic-b.mina
│ │ │ └── symbolic-a.mina
│ │ ├── json5
│ │ │ └── component.mina
│ │ ├── lang
│ │ │ ├── basic.mina
│ │ │ ├── custom-rule.mina
│ │ │ └── override-loader.mina
│ │ ├── resolve-components
│ │ │ ├── node_modules
│ │ │ │ ├── logo.mina
│ │ │ │ │ ├── dist
│ │ │ │ │ │ └── logo.mina
│ │ │ │ │ └── package.json
│ │ │ │ └── tab
│ │ │ │ │ ├── package.json
│ │ │ │ │ ├── tab-item.mina
│ │ │ │ │ └── tab.mina
│ │ │ └── src
│ │ │ │ ├── app.mina
│ │ │ │ ├── components
│ │ │ │ ├── a.mina
│ │ │ │ └── b.mina
│ │ │ │ └── pages
│ │ │ │ ├── c.mina
│ │ │ │ ├── d.mina
│ │ │ │ └── home.mina
│ │ ├── separation
│ │ │ ├── anotherUtil.ts
│ │ │ ├── es-page.es
│ │ │ ├── es-page.mina
│ │ │ ├── simple-page.mina
│ │ │ ├── simple-page.wxml
│ │ │ ├── simple-page.wxss
│ │ │ ├── ts-page.mina
│ │ │ ├── ts-page.ts
│ │ │ └── tsconfig.json
│ │ ├── subpackages
│ │ │ └── src
│ │ │ │ ├── app.mina
│ │ │ │ ├── components
│ │ │ │ ├── a.mina
│ │ │ │ ├── b.mina
│ │ │ │ ├── c.mina
│ │ │ │ └── d.mina
│ │ │ │ ├── pages
│ │ │ │ └── home.mina
│ │ │ │ ├── sub1
│ │ │ │ ├── page1.mina
│ │ │ │ └── page2.mina
│ │ │ │ └── sub2
│ │ │ │ └── page1.mina
│ │ ├── template
│ │ │ ├── header.wxml
│ │ │ ├── import.mina
│ │ │ ├── include.mina
│ │ │ ├── inline.mina
│ │ │ ├── logo.png
│ │ │ ├── message.wxml
│ │ │ └── subdir
│ │ │ │ └── page.mina
│ │ └── wxss
│ │ │ ├── cdn
│ │ │ └── postcss.config.js
│ │ │ ├── page.mina
│ │ │ └── url
│ │ │ └── postcss.config.js
│ ├── helpers
│ │ ├── babelrc
│ │ ├── compiler.js
│ │ ├── config-readers
│ │ │ └── yaml-to-mina-config-reader.js
│ │ ├── loaders
│ │ │ ├── debug-loader.js
│ │ │ ├── nothing-loader.js
│ │ │ ├── replace-blue-to-yellow.js
│ │ │ ├── scope-id-loader.js
│ │ │ └── yaml-to-mina-loader.js
│ │ └── transform
│ │ │ └── scope-id.js
│ ├── json5.js
│ ├── lang.js
│ ├── mina-entry-plugin.js
│ ├── mina-runtime-plugin.js
│ ├── resolve-components.js
│ ├── separation.js
│ ├── subpackages.js
│ ├── template.js
│ ├── transform.js
│ └── wxss.js
└── tsconfig.json
├── mina-runtime-webpack-plugin
├── .gitignore
├── .lintstagedrc.json
├── .prettierrc.js
├── LICENSE
├── README.md
├── package-lock.json
├── package.json
├── polyfill.js
├── src
│ └── index.ts
└── tsconfig.json
└── wxs-loader
├── .gitignore
├── .lintstagedrc.json
├── .prettierrc.js
├── LICENSE
├── README.md
├── package-lock.json
├── package.json
├── src
├── helpers
│ ├── extract.js
│ ├── get-public-path.js
│ ├── load-module.js
│ ├── relative.js
│ ├── resolve.js
│ ├── to-safe-output-path.js
│ └── visit.js
└── index.js
├── test
├── fixtures
│ ├── constants.wxs
│ ├── greet.wxs
│ ├── padding.wxs
│ └── pokemon
│ │ └── eevee.wxs
├── helpers
│ └── compiler.js
├── snapshots
│ ├── wxs.js.md
│ └── wxs.js.snap
└── wxs.js
└── tsconfig.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.mina linguist-language=Vue
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # dev
2 | .DS_Store
3 | node_modules
4 | !/packages/mina-loader/test/fixtures/resolve-components/node_modules
5 | npm-debug.log
6 | lerna-debug.log
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - "12"
5 | - "10"
6 |
7 | cache:
8 | directories:
9 | - $HOME/.npm
10 |
11 | before_install:
12 | - npm install --global npm@latest
13 | - npm --version
14 |
15 | install:
16 | - npx lerna bootstrap --ci
17 |
18 | script:
19 | - npx lerna run test
20 |
21 | notifications:
22 | webhooks: "https://www.travisbuddy.com/"
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
mina-webpack
2 | Mina single-file-component meets Webpack
3 | 
4 |
5 | [](https://travis-ci.org/tinajs/mina-webpack)
6 | [](http://makeapullrequest.com)
7 | [](https://app.fossa.io/projects/git%2Bgithub.com%2Ftinajs%2Fmina-webpack?ref=badge_small)
8 |
9 | ## Get Started
10 |
11 | We recommend you to get started with [template-mina](https://github.com/tinajs/template-mina):
12 |
13 | ```bash
14 | npm i -g sao
15 |
16 | sao mina my-app
17 | cd my-app
18 | npm start
19 | ```
20 |
21 | And see how to use with [TinaJS](https://tinajs.github.io/tina/#/guide/package-management-and-build-tools)
22 |
23 | ## Packages included
24 |
25 | - [mina-loader](./packages/mina-loader)
26 |
27 | [](https://www.npmjs.com/package/@tinajs/mina-loader)
28 | [](https://www.npmjs.com/package/@tinajs/mina-loader)
29 | [](./LICENSE)
30 |
31 | - [mina-runtime-webpack-plugin](./packages/mina-runtime-webpack-plugin)
32 |
33 | [](https://www.npmjs.com/package/@tinajs/mina-runtime-webpack-plugin)
34 | [](https://www.npmjs.com/package/@tinajs/mina-runtime-webpack-plugin)
35 | [](./LICENSE)
36 |
37 | - [mina-entry-webpack-plugin](./packages/mina-entry-webpack-plugin)
38 |
39 | [](https://www.npmjs.com/package/@tinajs/mina-entry-webpack-plugin)
40 | [](https://www.npmjs.com/package/@tinajs/mina-entry-webpack-plugin)
41 | [](./LICENSE)
42 |
43 | - [wxs-loader](./packages/wxs-loader)
44 |
45 | [](https://www.npmjs.com/package/@tinajs/wxs-loader)
46 | [](https://www.npmjs.com/package/@tinajs/wxs-loader)
47 | [](./LICENSE)
48 |
49 | ## Manual Installation
50 |
51 | ```bash
52 | npm i --save-dev \
53 | @tinajs/mina-entry-webpack-plugin \
54 | @tinajs/mina-runtime-webpack-plugin \
55 | @tinajs/mina-loader \
56 | @tinajs/wxs-loader
57 | ```
58 |
59 | ## Simplest Usage
60 |
61 | **webpack.config.js**:
62 |
63 | ```javascript
64 | const webpack = require("webpack");
65 | const MinaEntryPlugin = require("@tinajs/mina-entry-webpack-plugin");
66 | const MinaRuntimePlugin = require("@tinajs/mina-runtime-webpack-plugin");
67 | const resolve = require("path").resolve;
68 |
69 | module.exports = {
70 | context: resolve("src"),
71 | entry: "./app.mina",
72 | output: {
73 | path: resolve("dist"),
74 | filename: "[name]",
75 | publicPath: "/",
76 | globalObject: "wx"
77 | },
78 | module: {
79 | rules: [
80 | {
81 | test: /\.mina$/,
82 | use: {
83 | loader: "@tinajs/mina-loader",
84 | options: {
85 | loaders: {
86 | script: "babel-loader"
87 | }
88 | }
89 | }
90 | },
91 | {
92 | test: /\.wxs$/,
93 | use: [
94 | {
95 | loader: '@tinajs/wxs-loader',
96 | options: {
97 | name: 'wxs/[name].[hash:6].[ext]',
98 | },
99 | },
100 | ],
101 | },
102 | ]
103 | },
104 | plugins: [
105 | new MinaEntryPlugin({
106 | map: entry => ["es6-promise/dist/es6-promise.auto.js", entry]
107 | }),
108 | new MinaRuntimePlugin()
109 | ],
110 | optimization: {
111 | splitChunks: {
112 | chunks: 'all',
113 | name: "common.js",
114 | minChunks: 2,
115 | minSize: 0
116 | },
117 | runtimeChunk: {
118 | name: "runtime.js"
119 | }
120 | },
121 | mode: "none"
122 | };
123 | ```
124 |
125 | **app.mina**:
126 |
127 | ```xml
128 |
129 | {
130 | "pages": [
131 | "page.mina"
132 | ]
133 | }
134 |
135 |
136 |
144 | ```
145 |
146 | **page.mina**:
147 |
148 | ```xml
149 |
150 | {
151 | "window":{
152 | "navigationBarTitleText": "Hello, World!"
153 | }
154 | }
155 |
156 |
157 |
162 |
163 |
164 |
165 | {{ msg }}
166 |
167 |
168 |
169 |
179 | ```
180 |
181 | ## Examples
182 |
183 | - [mina-webpack - Full Example](./example)
184 | - [mina-loader - test](./packages/mina-loader/test)
185 | - [wxs-loader - test](./packages/wxs-loader/test)
186 | - [TinaJS - HackerNews Reader](https://github.com/tinajs/tina-hackernews)
187 |
188 | ## Related Projects
189 |
190 | ### Best to use with
191 |
192 | - [TinaJS](https://github.com/tinajs/tina)
193 |
194 | ### Scaffolds
195 |
196 | - [template-mina](https://github.com/tinajs/template-mina)
197 | - [ambar/new-mina](https://github.com/ambar/new-mina)
198 |
199 | ### Other package compiler (also alternatives)
200 |
201 | - [gulp-mina](https://github.com/tinajs/gulp-mina)
202 |
203 | ### Got inspiration from
204 |
205 | - [Cap32/wxapp-webpack-plugin](https://github.com/Cap32/wxapp-webpack-plugin)
206 | - [CantonJS/wxapp-boilerplate](https://github.com/cantonjs/wxapp-boilerplate)
207 | - [zezhipeng/mina-loader](https://github.com/zezhipeng/mina-loader)
208 | - [Vue - Single File Component](https://vuejs.org/v2/guide/single-file-components.html)
209 |
210 | [](https://github.com/tinajs/tina)
211 |
--------------------------------------------------------------------------------
/example/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["@babel/preset-env", {
4 | "modules": false,
5 | "loose": true
6 | }]
7 | ],
8 | "plugins": [
9 | ["@babel/plugin-transform-runtime", {
10 | "corejs": 2
11 | }],
12 | "@babel/plugin-proposal-class-properties",
13 | "@babel/plugin-proposal-export-default-from"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/example/.browserslistrc:
--------------------------------------------------------------------------------
1 | iOS 8
2 | ChromeAndroid 53
3 |
--------------------------------------------------------------------------------
/example/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/example/.gitattributes:
--------------------------------------------------------------------------------
1 | # GitLab
2 | # https://docs.gitlab.com/ee/user/project/highlighting.html
3 | *.wxml gitlab-language=xml
4 | *.wxss gitlab-language=css
5 | *.wxs gitlab-language=js
6 | *.mina gitlab-language=html
7 |
8 | # GitHub
9 | # https://github.com/github/linguist#overrides
10 | *.wxml linguist-language=xml
11 | *.wxss linguist-language=css
12 | *.wxs linguist-language=js
13 | *.mina linguist-language=html
14 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | /dist
2 |
--------------------------------------------------------------------------------
/example/.lintstagedrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "linters": {
3 | "*.{md,js,json}": ["prettier --write", "git add"]
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/example/.prettierrc.js:
--------------------------------------------------------------------------------
1 | // @see https://prettier.io/docs/en/options.html
2 | module.exports = {
3 | semi: false,
4 | singleQuote: true,
5 | trailingComma: 'es5',
6 | }
7 |
--------------------------------------------------------------------------------
/example/.vscode/setting.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "*.wxml": "xml",
4 | "*.wxss": "css",
5 | "*.wxs": "js",
6 | "*.mina": "vue"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # mina-webpack-examples
2 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@tinajs/mina-webpack-examples",
3 | "private": true,
4 | "description": "",
5 | "main": "index.js",
6 | "author": "yelo",
7 | "license": "MIT",
8 | "scripts": {
9 | "clean": "rimraf \"./dist/!(app.json)**\"",
10 | "precommit": "lint-staged",
11 | "prestart": "run-s clean",
12 | "prebuild": "run-s clean",
13 | "start": "webpack --watch --progress",
14 | "build": "cross-env NODE_ENV=production webpack"
15 | },
16 | "dependencies": {
17 | "@tinajs/tina-logo.mina": "^0.2.1",
18 | "@vant/weapp": "^1.3.2",
19 | "cowsay": "^1.5.0",
20 | "es6-promise": "^4.2.4",
21 | "iview-weapp": "^2.0.0"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "^7.1.0",
25 | "@babel/plugin-proposal-class-properties": "^7.1.0",
26 | "@babel/plugin-proposal-export-default-from": "^7.0.0",
27 | "@babel/plugin-transform-runtime": "^7.1.0",
28 | "@babel/preset-env": "^7.1.0",
29 | "@babel/runtime-corejs2": "^7.0.0",
30 | "@tinajs/mina-entry-webpack-plugin": "^1.5.0",
31 | "@tinajs/mina-loader": "^1.9.0",
32 | "@tinajs/mina-runtime-webpack-plugin": "^1.3.6",
33 | "@tinajs/wxml-loader": "0.3.1-fork.1",
34 | "@tinajs/wxs-loader": "^1.2.10",
35 | "babel-loader": "^8.0.4",
36 | "cross-env": "^5.1.1",
37 | "file-loader": "^1.1.11",
38 | "json5": "^2.2.2",
39 | "lint-staged": "^7.2.0",
40 | "npm-run-all": "^4.1.2",
41 | "postcss-loader": "^7.3.3",
42 | "precss": "^4.0.0",
43 | "prettier": "^1.19.1",
44 | "relative-file-loader": "^1.1.12",
45 | "rimraf": "^2.6.2",
46 | "uglifyjs-webpack-plugin": "^1.2.7",
47 | "url-loader": "^0.6.2",
48 | "webpack": "^5.94.0",
49 | "webpack-cli": "^3.3.12"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/example/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [require('precss')()],
3 | }
4 |
--------------------------------------------------------------------------------
/example/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "miniprogramRoot": "./dist",
3 | "compileType": "miniprogram",
4 | "setting": {
5 | "es6": false,
6 | "postcss": false,
7 | "minified": false,
8 | "uglifyFileName": false,
9 | "newFeature": true
10 | },
11 | "appid": "",
12 | "projectname": "mina-webpack-example"
13 | }
14 |
--------------------------------------------------------------------------------
/example/src/app.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "pages/home.mina",
5 | "pages/message.mina"
6 | ],
7 | "subPackages": [
8 | {
9 | "root": "packages/a",
10 | "pages": [
11 | "pages/home.mina"
12 | ]
13 | }
14 | ],
15 | "tabBar": {
16 | "list": [
17 | {
18 | "pagePath": "pages/home.mina",
19 | "text": "Home",
20 | "iconPath": "./images/tabs/home.png",
21 | "selectedIconPath": "./images/tabs/home-active.png"
22 | },
23 | {
24 | "pagePath": "pages/message.mina",
25 | "text": "Message",
26 | "iconPath": "./images/tabs/bell.png",
27 | "selectedIconPath": "./images/tabs/bell-active.png"
28 | }
29 | ]
30 | }
31 | }
32 |
33 |
34 |
43 |
--------------------------------------------------------------------------------
/example/src/common.wxss:
--------------------------------------------------------------------------------
1 | page {
2 | font-size: 12px;
3 | }
4 |
--------------------------------------------------------------------------------
/example/src/components/bar.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "component": true
4 | }
5 |
6 |
7 |
8 | bar
9 |
10 |
11 |
15 |
--------------------------------------------------------------------------------
/example/src/components/circular.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "circular": "circular.mina"
5 | },
6 | "component": true
7 | }
8 |
9 |
10 |
11 | Circular
12 |
13 |
14 |
18 |
--------------------------------------------------------------------------------
/example/src/components/classical.js:
--------------------------------------------------------------------------------
1 | Component({})
2 |
--------------------------------------------------------------------------------
/example/src/components/classical.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true
3 | }
4 |
--------------------------------------------------------------------------------
/example/src/components/classical.wxml:
--------------------------------------------------------------------------------
1 | classical component
2 |
--------------------------------------------------------------------------------
/example/src/components/foobar.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "bar": "./bar.mina"
5 | },
6 | "component": true
7 | }
8 |
9 |
10 |
11 | foo
12 |
13 |
14 |
18 |
--------------------------------------------------------------------------------
/example/src/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinajs/mina-webpack/954761f689772903fd7b2d3f83d1493435818076/example/src/images/logo.png
--------------------------------------------------------------------------------
/example/src/images/tabs/bell-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinajs/mina-webpack/954761f689772903fd7b2d3f83d1493435818076/example/src/images/tabs/bell-active.png
--------------------------------------------------------------------------------
/example/src/images/tabs/bell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinajs/mina-webpack/954761f689772903fd7b2d3f83d1493435818076/example/src/images/tabs/bell.png
--------------------------------------------------------------------------------
/example/src/images/tabs/home-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinajs/mina-webpack/954761f689772903fd7b2d3f83d1493435818076/example/src/images/tabs/home-active.png
--------------------------------------------------------------------------------
/example/src/images/tabs/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinajs/mina-webpack/954761f689772903fd7b2d3f83d1493435818076/example/src/images/tabs/home.png
--------------------------------------------------------------------------------
/example/src/packages/a/pages/home.mina:
--------------------------------------------------------------------------------
1 |
2 |
3 | This is subPage A
4 | this page should be lazy-loaded
5 |
6 |
7 |
8 |
11 |
12 |
13 |
16 |
--------------------------------------------------------------------------------
/example/src/pages/home.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "tina-logo": "~@tinajs/tina-logo.mina",
5 | "circular": "../components/circular.mina",
6 | "foobar": "/components/foobar.mina",
7 | "classical": "../components/classical",
8 | "i-button": "~iview-weapp/dist/button/index",
9 | "van-button": "~@vant/weapp/lib/button/index",
10 | }
11 | }
12 |
13 |
14 |
28 |
29 |
30 |
31 | {{msg}}
32 | Go to a page in a subpackage
33 |
34 |
35 |
36 |
37 | iview button
38 | vant button
39 |
40 |
41 |
42 |
58 |
--------------------------------------------------------------------------------
/example/src/pages/message.mina:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Roll: {{ random }}
7 | Now: {{ now }}
8 |
9 |
10 | var MAX = 100;
11 | module.exports = Math.floor(Math.random() * MAX);
12 |
13 |
14 |
15 |
16 |
17 |
20 |
--------------------------------------------------------------------------------
/example/src/template/greeting.wxml:
--------------------------------------------------------------------------------
1 | {{ greeting() }}
2 |
3 |
--------------------------------------------------------------------------------
/example/src/utils/dependency.js:
--------------------------------------------------------------------------------
1 | console.log('\u2665')
2 |
--------------------------------------------------------------------------------
/example/src/wxs/datetime/now.wxs:
--------------------------------------------------------------------------------
1 | var padding = require('../string/padding.wxs')
2 |
3 | var now = getDate();
4 |
5 | var year = now.getFullYear();
6 | var month = padding(2)(now.getMonth() + 1);
7 | var date = padding(2)(now.getDate());
8 | var hours = padding(2)(now.getHours());
9 | var minutes = padding(2)(now.getMinutes());
10 | var seconds = padding(2)(now.getSeconds());
11 |
12 | module.exports = year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + seconds;
13 |
--------------------------------------------------------------------------------
/example/src/wxs/greeting.wxs:
--------------------------------------------------------------------------------
1 | function random (array) {
2 | return array[Math.floor(Math.random() * array.length)]
3 | }
4 |
5 | var GREETING = [
6 | 'Hi',
7 | 'Glad to see you',
8 | 'How was your day',
9 | ]
10 |
11 | module.exports = function greeting () {
12 | return random(GREETING)
13 | }
14 |
--------------------------------------------------------------------------------
/example/src/wxs/string/padding.wxs:
--------------------------------------------------------------------------------
1 | var padding = function (digits) {
2 | return function pad (number) {
3 | var ceil = Math.pow(10, digits) + number;
4 | return ceil.toString().slice(1);
5 | };
6 | };
7 |
8 | module.exports = padding
9 |
--------------------------------------------------------------------------------
/example/webpack.config.js:
--------------------------------------------------------------------------------
1 | const { resolve } = require('path')
2 | const webpack = require('webpack')
3 | const MinaEntryPlugin = require('@tinajs/mina-entry-webpack-plugin')
4 | const MinaRuntimePlugin = require('@tinajs/mina-runtime-webpack-plugin')
5 |
6 | const isProduction = process.env.NODE_ENV === 'production'
7 |
8 | const loaders = {
9 | script: 'babel-loader',
10 | style: {
11 | loader: 'postcss-loader',
12 | options: {
13 | config: {
14 | path: resolve('./postcss.config.js'),
15 | },
16 | },
17 | },
18 | }
19 |
20 | module.exports = {
21 | context: resolve('src'),
22 | entry: './app.mina',
23 | output: {
24 | path: resolve(__dirname, 'dist'),
25 | filename: '[name]',
26 | publicPath: '/',
27 | globalObject: 'wx',
28 | },
29 | module: {
30 | rules: [
31 | {
32 | test: /\.mina$/,
33 | exclude: /node_modules/,
34 | use: [
35 | {
36 | loader: '@tinajs/mina-loader',
37 | options: {
38 | loaders,
39 | },
40 | },
41 | ],
42 | },
43 | {
44 | test: /\.mina$/,
45 | include: /node_modules/,
46 | use: '@tinajs/mina-loader',
47 | },
48 | {
49 | test: /\.js$/,
50 | exclude: /node_modules/,
51 | use: loaders.script,
52 | },
53 | {
54 | test: /\.(css|wxss)$/,
55 | exclude: /node_modules/,
56 | use: loaders.style,
57 | },
58 | {
59 | test: /\.(png|jpg|jpeg|gif|svg)$/,
60 | use: {
61 | loader: 'file-loader',
62 | options: {
63 | name: 'assets/[name].[hash:6].[ext]',
64 | },
65 | },
66 | },
67 | {
68 | test: /\.wxs$/,
69 | use: [
70 | {
71 | loader: '@tinajs/wxs-loader',
72 | options: {
73 | name: 'wxs/[path]/[name].[hash:6].[ext]',
74 | context: resolve('src/wxs'),
75 | },
76 | },
77 | ],
78 | },
79 | {
80 | test: /\.wxml$/,
81 | use: [
82 | {
83 | loader: 'relative-file-loader',
84 | options: {
85 | name: 'wxml/[name].[hash:6].[ext]',
86 | },
87 | },
88 | {
89 | loader: '@tinajs/wxml-loader',
90 | options: {
91 | raw: true,
92 | enforceRelativePath: true,
93 | root: resolve('src'),
94 | },
95 | },
96 | ],
97 | },
98 | ],
99 | },
100 | resolve: {
101 | symlinks: true,
102 | },
103 | plugins: [
104 | new webpack.EnvironmentPlugin({
105 | NODE_ENV: 'development',
106 | DEBUG: false,
107 | }),
108 | new MinaEntryPlugin({
109 | map: entry => ['es6-promise/dist/es6-promise.auto.js', entry],
110 | }),
111 | new MinaRuntimePlugin({
112 | runtime: './runtime.js',
113 | }),
114 | ],
115 | optimization: {
116 | splitChunks: {
117 | chunks: 'all',
118 | name: 'common.js',
119 | minChunks: 2,
120 | minSize: 0,
121 | },
122 | runtimeChunk: {
123 | name: 'runtime.js',
124 | },
125 | },
126 | mode: isProduction ? 'production' : 'none',
127 | }
128 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "lerna": "3.20.2",
3 | "packages": ["packages/*", "example"],
4 | "version": "independent"
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "config": {
4 | "commitizen": {
5 | "path": "cz-conventional-changelog"
6 | }
7 | },
8 | "devDependencies": {
9 | "husky": "^4.2.3",
10 | "lerna": "^6.4.1"
11 | },
12 | "scripts": {},
13 | "dependencies": {
14 | "debug": "^4.1.1"
15 | },
16 | "husky": {
17 | "hooks": {
18 | "pre-commit": "lerna run --concurrency 1 --stream precommit"
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/mina-entry-webpack-plugin/.gitignore:
--------------------------------------------------------------------------------
1 | lib/
2 |
--------------------------------------------------------------------------------
/packages/mina-entry-webpack-plugin/.lintstagedrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "linters": {
3 | "*.{md,js,json}": ["prettier --write", "git add"]
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/mina-entry-webpack-plugin/.prettierrc.js:
--------------------------------------------------------------------------------
1 | // @see https://prettier.io/docs/en/options.html
2 | module.exports = {
3 | semi: false,
4 | singleQuote: true,
5 | trailingComma: 'es5',
6 | }
7 |
--------------------------------------------------------------------------------
/packages/mina-entry-webpack-plugin/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/packages/mina-entry-webpack-plugin/README.md:
--------------------------------------------------------------------------------
1 | # mina-entry-webpack-plugin
2 |
3 | > Automaticly generates entries-list from mina files for [Webpack](https://webpack.js.org/)
4 |
5 | [](https://www.npmjs.com/package/@tinajs/mina-entry-webpack-plugin)
6 | [](https://www.npmjs.com/package/@tinajs/mina-entry-webpack-plugin)
7 | [](./LICENSE)
8 | [](http://makeapullrequest.com)
9 |
10 | ## Installation
11 |
12 | ```bash
13 | npm i --save-dev @tinajs/mina-entry-webpack-plugin
14 | ```
15 |
16 | ## Usage
17 |
18 | ```javascript
19 | /**
20 | * webpack.config.js
21 | */
22 | const webpack = require('webpack')
23 | const MinaEntryPlugin = require('@tinajs/mina-entry-webpack-plugin')
24 | const resolve = require('path').resolve
25 |
26 | // implement yourself if necessary
27 | const CustomFileTypeConfigReader = require('./custom-file-type-config-loader')
28 |
29 | module.exports = {
30 | context: resolve('src'),
31 | entry: './app.mina',
32 | output: {
33 | path: resolve('dist'),
34 | filename: '[name]',
35 | publicPath: '/',
36 | },
37 | module: {
38 | rules: [
39 | {
40 | test: /\.mina$/,
41 | use: {
42 | loader: '@tinajs/mina-loader',
43 | },
44 | },
45 | ],
46 | },
47 | plugins: [
48 | new MinaEntryPlugin({
49 | map: (entry) => ['es6-promise/dist/es6-promise.auto.js', entry],
50 | rules: [{
51 | {
52 | pattern: '**/*.custom-file-type',
53 | reader: CustomFileTypeConfigReader,
54 | },
55 | }],
56 | }),
57 | ],
58 | }
59 | ```
60 |
61 | For the best particle, you might also be interested in [mina-webpack](https://github.com/tinajs/mina-webpack/).
62 |
63 | ## Options
64 |
65 | | Name | Default | Description |
66 | | ------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
67 | | map | (e) => e | Mapper function for each entry. Useful for adding polyfill scripts. |
68 | | rules | [] | Rules of custom config readers. See https://github.com/tinajs/mina-webpack/blob/master/packages/mina-loader/test/mina-entry-plugin.js#L204-L264 for examples |
69 | | rules[].pattern | '' | [Pattern, using glob expressions](https://www.npmjs.com/package/minimatch) |
70 | | rules[].reader | ConfigReader | Custom config reader, should inherit from [ConfigReader](./lib/interfaces/config-reader.js) and implement its `getConfig` interface |
71 | | extensions | ... | The extension names of each block for the separation (classical) files. |
72 | | extensions.template | `['.wxml']` | The extension name of the `` block |
73 | | extensions.style | `['.wxss']` | The extension name of the `
16 |
17 |
18 |
19 | {{msg}}
20 |
21 |
22 |
23 |
24 |
34 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/enforce-relative-path/page.mina:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/app-basic.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "page-a.mina",
5 | "page-b.mina"
6 | ]
7 | }
8 |
9 |
10 |
13 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/app-custom-extensions.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "page-h",
5 | "page-i",
6 | ]
7 | }
8 |
9 |
10 |
13 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/app-inline-loaders.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "../../helpers/loaders/nothing-loader!page-a.mina",
5 | "../../helpers/loaders/nothing-loader!../../helpers/loaders/nothing-loader!page-b.mina"
6 | ]
7 | }
8 |
9 |
10 |
13 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/app-non-extname.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "page-c",
5 | "page-d",
6 | "page-e",
7 | "page-f"
8 | ]
9 | }
10 |
11 |
12 |
15 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/app-not-existed-file.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "page-a.mina",
5 | "page-not-existed.mina",
6 | ]
7 | }
8 |
9 |
10 |
13 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/app-symbolic.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "symbolic-a.mina",
5 | ]
6 | }
7 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/app-unknown-file-type.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "page-a.mina",
5 | "page-g.yaml",
6 | ]
7 | }
8 |
9 |
10 |
13 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/app-virtual-extname.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "page-c.virtual",
5 | "page-d.virtual"
6 | ]
7 | }
8 |
9 |
10 |
13 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/component-a.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "component": true
4 | }
5 |
6 |
7 |
8 | Component A
9 |
10 |
11 |
14 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/component-b.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true
3 | }
4 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/component-c.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "component": true
4 | }
5 |
6 |
7 |
8 | Component C
9 |
10 |
11 |
14 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/hi.js:
--------------------------------------------------------------------------------
1 | 'Hi'
2 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinajs/mina-webpack/954761f689772903fd7b2d3f83d1493435818076/packages/mina-loader/test/fixtures/entry/logo.png
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-a.mina:
--------------------------------------------------------------------------------
1 |
2 | Page A
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-b.mina:
--------------------------------------------------------------------------------
1 |
2 | Page B
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-c.js:
--------------------------------------------------------------------------------
1 | 'Page C'
2 | require('./hi.js')
3 | require('./logo.png')
4 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-c.json:
--------------------------------------------------------------------------------
1 | {
2 | "usingComponents": {
3 | "a": "./component-a.mina"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-d.wxml:
--------------------------------------------------------------------------------
1 | Page D
2 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-e.json:
--------------------------------------------------------------------------------
1 | {
2 | "usingComponents": {
3 | "b": "./component-b",
4 | "c": "./component-c.mina"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-f.wxss:
--------------------------------------------------------------------------------
1 | view {
2 | display: none;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-g.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | usingComponents:
3 | b: ./component-b
4 | c: ./component-c.mina
5 | ---
6 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-h.ttml:
--------------------------------------------------------------------------------
1 | Page H
2 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-i.js:
--------------------------------------------------------------------------------
1 | 'Page I'
2 | require('./hi.js')
3 | require('./logo.png')
4 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/page-i.ttml:
--------------------------------------------------------------------------------
1 | Page I
2 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/symbolic-a.mina:
--------------------------------------------------------------------------------
1 | ../extra-resources/symbolic-a.mina
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/entry/symbolic-b.mina:
--------------------------------------------------------------------------------
1 | ../extra-resources/subdir/symbolic-b.mina
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/extra-resources/github.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "component": true
4 | }
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/extra-resources/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinajs/mina-webpack/954761f689772903fd7b2d3f83d1493435818076/packages/mina-loader/test/fixtures/extra-resources/github.png
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/extra-resources/subdir/symbolic-b.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "component": true
4 | }
5 |
6 |
7 |
8 | Symbolic B
9 |
10 |
11 |
14 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/extra-resources/symbolic-a.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "b": "/symbolic-b.mina"
5 | }
6 | }
7 |
8 |
9 |
10 | Symbolic A
11 |
12 |
13 |
16 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/json5/component.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | component: true,
4 | }
5 |
6 |
7 |
8 | my component
9 |
10 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/lang/basic.mina:
--------------------------------------------------------------------------------
1 |
8 |
9 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/lang/custom-rule.mina:
--------------------------------------------------------------------------------
1 |
7 |
8 |
15 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/lang/override-loader.mina:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/node_modules/logo.mina/dist/logo.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "component": true
4 | }
5 |
6 |
7 |
8 | my logo
9 |
10 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/node_modules/logo.mina/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "main": "dist/logo.mina"
4 | }
5 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/node_modules/tab/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "main": "tab.mina"
4 | }
5 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/node_modules/tab/tab-item.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "component": true
4 | }
5 |
6 |
7 |
8 | my logo
9 |
10 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/node_modules/tab/tab.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "component": true,
4 | "usingComponents": {
5 | "logo": "~logo.mina",
6 | "tab-item": "tab-item.mina"
7 | }
8 | }
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/src/app.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "pages/home.mina"
5 | ]
6 | }
7 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/src/components/a.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | component: true,
4 | }
5 |
6 |
7 |
8 | a component
9 |
10 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/src/components/b.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | component: true,
4 | }
5 |
6 |
7 |
8 | b component
9 |
10 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/src/pages/c.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | component: true,
4 | }
5 |
6 |
7 |
8 | c component
9 |
10 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/src/pages/d.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | component: true,
4 | }
5 |
6 |
7 |
8 | d component
9 |
10 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/resolve-components/src/pages/home.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "a": "/components/a.mina",
5 | "b": "../components/b.mina",
6 | "c": "c.mina",
7 | "d": "./d.mina",
8 | "logo": "~logo.mina",
9 | "tab": "~tab",
10 | "mp-badge": "weui-miniprogram/badge/badge",
11 | "plugin": "plugin://foobar/component",
12 | "dynamicLib": "dynamicLib://swan-sitemap-lib/component"
13 | }
14 | }
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
31 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/separation/anotherUtil.ts:
--------------------------------------------------------------------------------
1 | export default async function AnotherUtils(params: {
2 | x: number
3 | y: number
4 | }): Promise {
5 | return params.x * params.y
6 | }
7 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/separation/es-page.es:
--------------------------------------------------------------------------------
1 | Page({
2 | onLoad () {
3 | this.setData({
4 | msg: 'Hello from ES Page!',
5 | })
6 | },
7 | })
8 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/separation/es-page.mina:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{msg}}
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/separation/simple-page.mina:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/separation/simple-page.wxml:
--------------------------------------------------------------------------------
1 | Page
2 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/separation/simple-page.wxss:
--------------------------------------------------------------------------------
1 | .view {
2 | .image {
3 | width: 0;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/separation/ts-page.mina:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{msg}}
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/separation/ts-page.ts:
--------------------------------------------------------------------------------
1 | type PageDefs = { onLoad: () => void }
2 |
3 | declare var Page: (PageDefs) => any
4 |
5 | type WxPage = {
6 | setData: (object) => void
7 | }
8 |
9 | import Util from './anotherUtil'
10 |
11 | Page({
12 | onLoad(this: WxPage) {
13 | Util({ x: 1, y: 2 }).then(result => {
14 | this.setData({
15 | msg: 'Hello from TS Page!',
16 | result,
17 | })
18 | })
19 | },
20 | })
21 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/separation/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["es2015"],
4 | "target": "es5"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/subpackages/src/app.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "pages": [
4 | "pages/home.mina"
5 | ],
6 | "subPackages": [
7 | {
8 | "name": "sub1",
9 | "root": "sub1",
10 | "pages": [
11 | "page1.mina",
12 | "page2.mina",
13 | ]
14 | },
15 | {
16 | "name": "sub2",
17 | "root": "sub2",
18 | "pages": [
19 | "page1.mina",
20 | ],
21 | "independent": true,
22 | },
23 | ]
24 | }
25 |
26 |
27 |
30 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/subpackages/src/components/a.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "c": "c.mina",
5 | "d": "d.mina",
6 | }
7 | }
8 |
9 |
10 |
11 |
12 | a component
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/subpackages/src/components/b.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "d": "d.mina",
5 | }
6 | }
7 |
8 |
9 |
10 |
11 | b component
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/subpackages/src/components/c.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | component: true,
4 | }
5 |
6 |
7 |
8 | a component
9 |
10 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/subpackages/src/components/d.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | component: true,
4 | }
5 |
6 |
7 |
8 | a component
9 |
10 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/subpackages/src/pages/home.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "logo": "~logo.mina",
5 | }
6 | }
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/subpackages/src/sub1/page1.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "a": "/components/a.mina",
5 | "b": "/components/b.mina",
6 | }
7 | }
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/subpackages/src/sub1/page2.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "a": "/components/a.mina",
5 | }
6 | }
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/subpackages/src/sub2/page1.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "usingComponents": {
4 | "b": "/components/b.mina",
5 | }
6 | }
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/template/header.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/template/import.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "name": "mina"
4 | }
5 |
6 |
7 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
31 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/template/include.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "name": "mina"
4 | }
5 |
6 |
7 |
12 |
13 |
14 |
15 |
16 | body
17 |
18 |
19 |
20 |
31 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/template/inline.mina:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "name": "mina"
4 | }
5 |
6 |
7 |
12 |
13 |
14 |
15 |
16 | odd
17 |
18 |
19 | even
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
34 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/template/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinajs/mina-webpack/954761f689772903fd7b2d3f83d1493435818076/packages/mina-loader/test/fixtures/template/logo.png
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/template/message.wxml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 | {{index}}: {{msg}}
9 | Time: {{time}}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/template/subdir/page.mina:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/wxss/cdn/postcss.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const CDN_PREFIX = 'https://cdn.url/'
3 | const CDN_DIR = path.relative(
4 | process.cwd(),
5 | path.resolve(__dirname, '..', '.dist/cdn/')
6 | )
7 |
8 | module.exports = {
9 | plugins: [
10 | require('postcss-url')([
11 | {
12 | url: 'copy',
13 | basePath: path.resolve(__dirname, '..'),
14 | assetsPath: CDN_DIR,
15 | useHash: true,
16 | hashOptions: {
17 | shrink: 6,
18 | append: true,
19 | },
20 | },
21 | {
22 | url: ({ url }) => `${CDN_PREFIX}${url.replace(`${CDN_DIR}/`, '')}`,
23 | multi: true,
24 | },
25 | ]),
26 | ],
27 | }
28 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/wxss/page.mina:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/fixtures/wxss/url/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [require('postcss-url')({ url: 'inline' })],
3 | }
4 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/helpers/babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": [
7 | "iOS 8",
8 | "ChromeAndroid 53"
9 | ]
10 | }
11 | ]
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/helpers/compiler.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import webpack from 'webpack'
3 | import merge from 'webpack-merge'
4 | import MemoryFS from 'memory-fs'
5 |
6 | const root = path.resolve(__dirname, '..')
7 |
8 | export default (options = {}) => {
9 | const mfs = new MemoryFS()
10 |
11 | options = merge.smart(
12 | {
13 | mode: 'none',
14 | context: root,
15 | output: {
16 | path: '/',
17 | publicPath: '/',
18 | },
19 | module: {
20 | rules: [
21 | {
22 | test: /\.mina$/,
23 | use: {
24 | loader: require.resolve('../..'),
25 | // TODO this should'be add .loaders to configure different loaders for script/style
26 | },
27 | },
28 | {
29 | test: /\.png$/,
30 | use: {
31 | loader: 'file-loader',
32 | options: {
33 | name: 'assets/[name].[hash:6].[ext]',
34 | esModule: false,
35 | },
36 | },
37 | },
38 | {
39 | test: /\.wxml$/,
40 | use: [
41 | {
42 | loader: 'file-loader',
43 | options: {
44 | name: 'wxml/[name].[hash:6].[ext]',
45 | esModule: false,
46 | },
47 | },
48 | {
49 | loader: '@tinajs/wxml-loader',
50 | options: {
51 | raw: true,
52 | },
53 | },
54 | ],
55 | },
56 | ],
57 | },
58 | },
59 | options
60 | )
61 |
62 | return {
63 | mfs,
64 | compile() {
65 | const compiler = webpack(options)
66 | compiler.outputFileSystem = mfs
67 | return new Promise((resolve, reject) => {
68 | compiler.run((err, stats) => {
69 | if (err) {
70 | reject(err)
71 | } else {
72 | resolve(stats)
73 | }
74 | })
75 | })
76 | },
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/helpers/config-readers/yaml-to-mina-config-reader.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const fm = require('front-matter')
3 | const { ConfigReader } = require('@tinajs/mina-entry-webpack-plugin')
4 |
5 | class YamlConfigReader extends ConfigReader {
6 | static getConfig(filePath) {
7 | let plain = fs.readFileSync(filePath, 'utf8')
8 | return fm(plain).attributes
9 | }
10 | }
11 |
12 | module.exports = YamlConfigReader
13 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/helpers/loaders/debug-loader.js:
--------------------------------------------------------------------------------
1 | module.exports = function(source) {
2 | console.log('[debug loader]', this)
3 | return source
4 | }
5 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/helpers/loaders/nothing-loader.js:
--------------------------------------------------------------------------------
1 | module.exports = source => source
2 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/helpers/loaders/replace-blue-to-yellow.js:
--------------------------------------------------------------------------------
1 | /**
2 | * A loader for testing, replacing the `blue` in the code to `yellow`
3 | */
4 |
5 | module.exports = function(source) {
6 | return source.replace(/blue/g, 'yellow')
7 | }
8 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/helpers/loaders/scope-id-loader.js:
--------------------------------------------------------------------------------
1 | const { relative } = require('path')
2 | const { getHashDigest } = require('loader-utils')
3 |
4 | module.exports = function() {
5 | const id = getHashDigest(
6 | Buffer.from(relative(this.rootContext, this.resourcePath)),
7 | 'md5',
8 | 'hex',
9 | 8
10 | )
11 | return `module.exports = ${JSON.stringify(id)}`
12 | }
13 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/helpers/loaders/yaml-to-mina-loader.js:
--------------------------------------------------------------------------------
1 | const fm = require('front-matter')
2 |
3 | module.exports = source => {
4 | return `${JSON.stringify(fm(source).attributes)}`
5 | }
6 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/helpers/transform/scope-id.js:
--------------------------------------------------------------------------------
1 | const { getHashDigest } = require('loader-utils')
2 |
3 | module.exports = function(mina) {
4 | const id = getHashDigest(Buffer.from(mina.name), 'md5', 'hex', 8)
5 | mina.blocks.forEach(block => {
6 | if (block.tag === 'script') {
7 | block.content = `module.exports = ${JSON.stringify(id)}`
8 | } else {
9 | block.content = id
10 | }
11 | })
12 | return mina
13 | }
14 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/json5.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import test from 'ava'
3 | import { expect } from 'chai'
4 | import compiler from './helpers/compiler'
5 |
6 | const resolveRelative = path.resolve.bind(null, __dirname)
7 |
8 | function createCompiler({ minimize }) {
9 | return compiler({
10 | context: resolveRelative('fixtures/json5'),
11 | entry: './component.mina',
12 | output: {
13 | filename: 'component.js',
14 | },
15 | module: {
16 | rules: [
17 | {
18 | test: /\.mina$/,
19 | use: {
20 | loader: require.resolve('..'),
21 | options: {
22 | minimize,
23 | loaders: {
24 | script: 'babel-loader',
25 | },
26 | },
27 | },
28 | },
29 | ],
30 | },
31 | })
32 | }
33 |
34 | test('use json5 to parse config', async t => {
35 | const { compile, mfs } = createCompiler({ minimize: false })
36 | await compile()
37 | const got = JSON.parse(mfs.readFileSync('/component.json', 'utf-8'))
38 | const expected = {
39 | component: true,
40 | }
41 | t.deepEqual(got, expected)
42 | t.deepEqual(
43 | mfs.readFileSync('/component.json', 'utf-8'),
44 | JSON.stringify(expected, null, 2)
45 | )
46 | t.pass()
47 | })
48 |
49 | test('use json5 to parse config with minimize', async t => {
50 | const { compile, mfs } = createCompiler({ minimize: true })
51 | await compile()
52 | const got = JSON.parse(mfs.readFileSync('/component.json', 'utf-8'))
53 | const expected = {
54 | component: true,
55 | }
56 | t.deepEqual(got, expected)
57 | t.deepEqual(
58 | mfs.readFileSync('/component.json', 'utf-8'),
59 | JSON.stringify(expected)
60 | )
61 | t.pass()
62 | })
63 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/lang.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 | import compiler from './helpers/compiler'
3 |
4 | test('use lang attribute simply with loader name', async t => {
5 | const { compile, mfs } = compiler({
6 | entry: './fixtures/lang/basic.mina',
7 | output: {
8 | filename: 'fixtures/lang/basic.js',
9 | },
10 | })
11 | const stats = await compile()
12 |
13 | t.is(
14 | mfs.readFileSync('/fixtures/lang/basic.wxss', 'utf8'),
15 | '.parent .child {\n color: #333;\n}\n'
16 | )
17 |
18 | t.pass()
19 | })
20 |
21 | test('use lang attribute with extra rules', async t => {
22 | const { compile, mfs } = compiler({
23 | entry: './fixtures/lang/custom-rule.mina',
24 | output: {
25 | filename: 'fixtures/lang/custom-rule.js',
26 | },
27 | module: {
28 | rules: [
29 | {
30 | test: /\.mina$/,
31 | use: {
32 | loader: require.resolve('..'),
33 | options: {
34 | languages: {
35 | yellowify: './helpers/loaders/replace-blue-to-yellow',
36 | },
37 | },
38 | },
39 | },
40 | ],
41 | },
42 | })
43 | const stats = await compile()
44 |
45 | t.true(
46 | mfs
47 | .readFileSync('/fixtures/lang/custom-rule.js', 'utf8')
48 | .includes("console.log('yellow')")
49 | )
50 | t.false(
51 | mfs
52 | .readFileSync('/fixtures/lang/custom-rule.js', 'utf8')
53 | .includes("console.log('blue')")
54 | )
55 | t.is(
56 | mfs.readFileSync('/fixtures/lang/custom-rule.wxss', 'utf8'),
57 | 'text.yellow {\n color: #00f;\n background: yellow;\n}'
58 | )
59 |
60 | t.pass()
61 | })
62 |
63 | test('use lang attribute should override loaders options', async t => {
64 | const { compile, mfs } = compiler({
65 | entry: './fixtures/lang/override-loader.mina',
66 | output: {
67 | filename: 'fixtures/lang/override-loader.js',
68 | },
69 | module: {
70 | rules: [
71 | {
72 | test: /\.mina$/,
73 | use: {
74 | loader: require.resolve('..'),
75 | options: {
76 | loaders: {
77 | script: 'babel-loader',
78 | },
79 | languages: {
80 | yellowify: './helpers/loaders/replace-blue-to-yellow',
81 | },
82 | },
83 | },
84 | },
85 | ],
86 | },
87 | })
88 | const stats = await compile()
89 |
90 | t.true(
91 | mfs
92 | .readFileSync('/fixtures/lang/override-loader.js', 'utf8')
93 | .includes("console.log('yellow')")
94 | )
95 | t.false(
96 | mfs
97 | .readFileSync('/fixtures/lang/override-loader.js', 'utf8')
98 | .includes("console.log('blue')")
99 | )
100 |
101 | t.true(
102 | mfs
103 | .readFileSync('/fixtures/lang/override-loader.js', 'utf8')
104 | .includes('onLoad () {')
105 | )
106 | t.false(
107 | mfs
108 | .readFileSync('/fixtures/lang/override-loader.js', 'utf8')
109 | .includes('onLoad: function onLoad() {')
110 | )
111 |
112 | t.pass()
113 | })
114 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/mina-runtime-plugin.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import test from 'ava'
3 | import MinaRuntimePlugin from '@tinajs/mina-runtime-webpack-plugin'
4 | import compiler from './helpers/compiler'
5 |
6 | const resolveRelative = path.resolve.bind(null, __dirname)
7 |
8 | test('use MinaRuntimePlugin', async t => {
9 | const { compile, mfs } = compiler({
10 | context: resolveRelative('fixtures/basic'),
11 | entry: {
12 | 'app.js': './app.mina',
13 | 'page.js': './page.mina',
14 | },
15 | output: {
16 | filename: '[name]',
17 | globalObject: 'wx',
18 | },
19 | plugins: [new MinaRuntimePlugin()],
20 | optimization: {
21 | splitChunks: {
22 | chunks: 'all',
23 | name: 'common.js',
24 | minChunks: 2,
25 | minSize: 0,
26 | },
27 | runtimeChunk: {
28 | name: 'runtime.js',
29 | },
30 | },
31 | })
32 |
33 | await compile()
34 |
35 | const expectedStartsWith = `;require('./runtime.js');require('./common.js');(wx["webpackJsonp"] = wx["webpackJsonp"] || []).push(`
36 | const expectedRuntimeIncludes = `polyfill('parseInt', parseInt)`
37 |
38 | t.true(mfs.existsSync('/runtime.js'))
39 | t.true(
40 | mfs.readFileSync('/runtime.js', 'utf8').includes(expectedRuntimeIncludes)
41 | )
42 | t.true(mfs.existsSync('/common.js'))
43 | t.true(
44 | mfs.readFileSync('/common.js', 'utf8').includes("console.log('\\u2665')")
45 | )
46 | t.true(
47 | mfs
48 | .readFileSync('/common.js', 'utf8')
49 | .includes("console.log('\\ud83d\\udc95')")
50 | )
51 |
52 | t.true(mfs.readFileSync('/app.js', 'utf8').startsWith(expectedStartsWith))
53 | t.true(mfs.readFileSync('/page.js', 'utf8').startsWith(expectedStartsWith))
54 | t.true(mfs.readFileSync('/app.js', 'utf8').includes('Hello from App!'))
55 | t.true(mfs.readFileSync('/page.js', 'utf8').includes('Hello from Page!'))
56 | t.false(
57 | mfs.readFileSync('/app.js', 'utf8').includes("console.log('\\u2665')")
58 | )
59 | t.false(
60 | mfs
61 | .readFileSync('/app.js', 'utf8')
62 | .includes("console.log('\\ud83d\\udc95')")
63 | )
64 | t.false(
65 | mfs.readFileSync('/page.js', 'utf8').includes("console.log('\\u2665')")
66 | )
67 | t.false(
68 | mfs
69 | .readFileSync('/page.js', 'utf8')
70 | .includes("console.log('\\ud83d\\udc95')")
71 | )
72 |
73 | t.pass()
74 | })
75 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/resolve-components.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import test from 'ava'
3 | import MinaEntryPlugin from '@tinajs/mina-entry-webpack-plugin'
4 | import compiler from './helpers/compiler'
5 |
6 | const resolveRelative = path.resolve.bind(null, __dirname)
7 |
8 | test('resolve components', async t => {
9 | const { compile, mfs } = compiler({
10 | context: resolveRelative('fixtures/resolve-components/src'),
11 | entry: 'app.mina',
12 | output: {
13 | filename: 'app.js',
14 | },
15 | plugins: [new MinaEntryPlugin()],
16 | })
17 |
18 | await compile()
19 |
20 | t.deepEqual(JSON.parse(mfs.readFileSync('/pages/home.json', 'utf-8')), {
21 | usingComponents: {
22 | a: './../components/a',
23 | b: './../components/b',
24 | c: './c',
25 | d: './d',
26 | logo: './../_/_node_modules_/logo.mina/dist/logo',
27 | tab: './../_/_node_modules_/tab/tab',
28 | 'mp-badge': 'weui-miniprogram/badge/badge',
29 | plugin: 'plugin://foobar/component',
30 | dynamicLib: 'dynamicLib://swan-sitemap-lib/component',
31 | },
32 | })
33 |
34 | t.deepEqual(
35 | JSON.parse(mfs.readFileSync('/_/_node_modules_/tab/tab.json', 'utf-8')),
36 | {
37 | component: true,
38 | usingComponents: {
39 | logo: './../logo.mina/dist/logo',
40 | 'tab-item': './tab-item',
41 | },
42 | }
43 | )
44 |
45 | t.pass()
46 | })
47 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/separation.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import test from 'ava'
3 | import precss from 'precss'
4 | import compiler from './helpers/compiler'
5 |
6 | const resolveRelative = path.resolve.bind(null, __dirname)
7 |
8 | test('load separated source files', async t => {
9 | const { compile, mfs } = compiler({
10 | context: resolveRelative('fixtures/separation'),
11 | entry: './simple-page.mina',
12 | output: {
13 | filename: 'simple-page.js',
14 | },
15 | module: {
16 | rules: [
17 | {
18 | test: /\.mina$/,
19 | use: {
20 | loader: require.resolve('..'),
21 | },
22 | },
23 | {
24 | test: /\.wxss$/,
25 | use: {
26 | loader: 'postcss-loader',
27 | options: {
28 | plugins: [precss],
29 | },
30 | },
31 | },
32 | ],
33 | },
34 | })
35 |
36 | const stats = await compile()
37 |
38 | t.deepEqual(stats.compilation.errors, [])
39 |
40 | t.is(
41 | mfs.readFileSync('/simple-page.wxml', 'utf8'),
42 | 'Page \n'
43 | )
44 | t.is(
45 | mfs.readFileSync('/simple-page.wxss', 'utf8'),
46 | '.view .image {\n width: 0;\n }\n'
47 | )
48 |
49 | t.pass()
50 | })
51 |
52 | test('load separated .ts source file', async t => {
53 | const { compile, mfs } = compiler({
54 | context: resolveRelative('fixtures/separation'),
55 | entry: './ts-page.mina',
56 | output: {
57 | filename: 'ts-page.js',
58 | },
59 | resolve: {
60 | extensions: ['.ts', '.js'],
61 | },
62 | module: {
63 | rules: [
64 | {
65 | test: /\.mina$/,
66 | use: {
67 | loader: require.resolve('..'),
68 | },
69 | },
70 | {
71 | test: /\.ts$/,
72 | use: {
73 | loader: 'ts-loader',
74 | options: {
75 | appendTsSuffixTo: [/\.mina$/],
76 | },
77 | },
78 | },
79 | ],
80 | },
81 | })
82 |
83 | await compile()
84 | t.false(mfs.readFileSync('/ts-page.js', 'utf8').includes('onLoad () {'))
85 | t.true(
86 | mfs.readFileSync('/ts-page.js', 'utf8').includes('onLoad: function () {')
87 | )
88 | t.true(
89 | mfs.readFileSync('/ts-page.js', 'utf8').includes('Hello from TS Page!')
90 | )
91 | // TypeScript targeting ES5 should shim generator and await syntax
92 | t.true(mfs.readFileSync('/ts-page.js', 'utf8').includes('return __generator'))
93 | t.pass()
94 | })
95 |
96 | test('load separated .es source file', async t => {
97 | const { compile, mfs } = compiler({
98 | context: resolveRelative('fixtures/separation'),
99 | entry: './es-page.mina',
100 | output: {
101 | filename: 'es-page.js',
102 | },
103 | module: {
104 | rules: [
105 | {
106 | test: /\.mina$/,
107 | use: {
108 | loader: require.resolve('..'),
109 | },
110 | },
111 | {
112 | test: /\.es$/,
113 | use: {
114 | loader: 'babel-loader',
115 | options: {
116 | presets: [['@babel/preset-env']],
117 | },
118 | },
119 | },
120 | ],
121 | },
122 | })
123 |
124 | await compile()
125 | t.false(mfs.readFileSync('/es-page.js', 'utf8').includes('onLoad () {'))
126 | t.true(
127 | mfs
128 | .readFileSync('/es-page.js', 'utf8')
129 | .includes('onLoad: function onLoad() {')
130 | )
131 | t.true(
132 | mfs.readFileSync('/es-page.js', 'utf8').includes('Hello from ES Page!')
133 | )
134 | t.pass()
135 | })
136 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/subpackages.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import test from 'ava'
3 | import MinaEntryPlugin from '@tinajs/mina-entry-webpack-plugin'
4 | import compiler from './helpers/compiler'
5 |
6 | const resolveRelative = path.resolve.bind(null, __dirname)
7 |
8 | test('subpackages', async t => {
9 | const { compile, mfs } = compiler({
10 | context: resolveRelative('fixtures/subpackages/src'),
11 | entry: 'app.mina',
12 | output: {
13 | filename: 'app.js',
14 | },
15 | plugins: [new MinaEntryPlugin()],
16 | })
17 |
18 | await compile()
19 | // app
20 | t.deepEqual(JSON.parse(mfs.readFileSync('/app.json', 'utf-8')), {
21 | pages: ['pages/home'],
22 | subPackages: [
23 | {
24 | root: 'sub1',
25 | pages: ['page1', 'page2'],
26 | },
27 | {
28 | root: 'sub2',
29 | pages: ['page1'],
30 | independent: true, // support independent
31 | },
32 | ],
33 | })
34 | // sub1
35 | t.deepEqual(JSON.parse(mfs.readFileSync('/sub1/page1.json', 'utf-8')), {
36 | usingComponents: {
37 | a: './_/components/a', // a is moved to sub1
38 | b: './../components/b', // b is shared from sub1, sub2, so it's not moved
39 | },
40 | })
41 | // sub2
42 | t.deepEqual(JSON.parse(mfs.readFileSync('/sub2/page1.json', 'utf-8')), {
43 | usingComponents: {
44 | b: './../components/b', // b is shared from sub1, sub2, so it's not moved
45 | },
46 | })
47 | // a is only used by sub1, it is moved
48 | t.deepEqual(
49 | JSON.parse(mfs.readFileSync('/sub1/_/components/a.json', 'utf-8')),
50 | {
51 | usingComponents: {
52 | c: './c', // c is also moved
53 | d: './../../../components/d', // d is not moved
54 | },
55 | }
56 | )
57 | // b is shared by sub1 and sub2, it is not moved
58 | t.deepEqual(JSON.parse(mfs.readFileSync('/components/b.json', 'utf-8')), {
59 | usingComponents: {
60 | d: './d', // d is not moved
61 | },
62 | })
63 | // c is only used by a, it is moved
64 | t.deepEqual(
65 | JSON.parse(mfs.readFileSync('/sub1/_/components/c.json', 'utf-8')),
66 | {
67 | component: true,
68 | }
69 | )
70 | // d is shared by a and b, it's not moved
71 | t.deepEqual(JSON.parse(mfs.readFileSync('/components/d.json', 'utf-8')), {
72 | component: true,
73 | })
74 |
75 | t.pass()
76 | })
77 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/template.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import test from 'ava'
3 | import { expect } from 'chai'
4 | import compiler from './helpers/compiler'
5 |
6 | const resolveRelative = path.resolve.bind(null, __dirname)
7 |
8 | test('inline template', async t => {
9 | const { compile, mfs } = compiler({
10 | entry: './fixtures/template/inline.mina',
11 | output: {
12 | filename: 'fixtures/template/inline.js',
13 | },
14 | })
15 | const stats = await compile()
16 |
17 | t.true(
18 | mfs.readFileSync('/fixtures/template/inline.js', 'utf8').includes('loaded')
19 | )
20 | t.is(
21 | mfs.readFileSync('/fixtures/template/inline.wxml', 'utf8'),
22 | '\n \n odd \n \n \n even \n \n \n \n \n'
23 | )
24 | t.is(
25 | mfs.readFileSync('/fixtures/template/inline.wxss', 'utf8'),
26 | 'view {\n color: #00f;\n}'
27 | )
28 | t.is(
29 | mfs.readFileSync('/fixtures/template/inline.json', 'utf8'),
30 | '{\n "name": "mina"\n}'
31 | )
32 |
33 | t.pass()
34 | })
35 |
36 | test('import template', async t => {
37 | const { compile, mfs } = compiler({
38 | entry: './fixtures/template/import.mina',
39 | output: {
40 | filename: 'fixtures/template/import.js',
41 | },
42 | })
43 | const stats = await compile()
44 |
45 | t.is(
46 | mfs.readFileSync('/wxml/message.86e9ca.wxml', 'utf8'),
47 | '\n\n \n {{index}}: {{msg}} \n Time: {{time}} \n \n\n'
48 | )
49 |
50 | t.true(
51 | mfs
52 | .readFileSync('/fixtures/template/import.js', 'utf8')
53 | .includes('this is a template')
54 | )
55 | t.is(
56 | mfs.readFileSync('/fixtures/template/import.wxml', 'utf8'),
57 | '\n \n \n'
58 | )
59 | t.is(
60 | mfs.readFileSync('/fixtures/template/import.wxss', 'utf8'),
61 | 'view {\n color: #00f;\n}'
62 | )
63 | t.is(
64 | mfs.readFileSync('/fixtures/template/import.json', 'utf8'),
65 | '{\n "name": "mina"\n}'
66 | )
67 |
68 | t.pass()
69 | })
70 |
71 | test('include template', async t => {
72 | const { compile, mfs } = compiler({
73 | entry: './fixtures/template/include.mina',
74 | output: {
75 | filename: 'fixtures/template/include.js',
76 | },
77 | })
78 | const stats = await compile()
79 |
80 | t.true(mfs.existsSync('/assets/logo.349b7b.png'))
81 | t.is(
82 | mfs.readFileSync('/wxml/header.d14cab.wxml', 'utf8'),
83 | '\n\n'
84 | )
85 |
86 | t.true(
87 | mfs
88 | .readFileSync('/fixtures/template/include.js', 'utf8')
89 | .includes('this is a template')
90 | )
91 | t.is(
92 | mfs.readFileSync('/fixtures/template/include.wxml', 'utf8'),
93 | '\n \n body\n'
94 | )
95 | t.is(
96 | mfs.readFileSync('/fixtures/template/include.wxss', 'utf8'),
97 | 'view {\n color: #00f;\n}'
98 | )
99 | t.is(
100 | mfs.readFileSync('/fixtures/template/include.json', 'utf8'),
101 | '{\n "name": "mina"\n}'
102 | )
103 |
104 | t.pass()
105 | })
106 |
107 | test('use template from different paths', async t => {
108 | const { compile, mfs } = compiler({
109 | context: resolveRelative('fixtures/template'),
110 | entry: {
111 | 'import.js': './import.mina',
112 | 'subdir/page.js': './subdir/page.mina',
113 | },
114 | output: {
115 | filename: '[name]',
116 | },
117 | })
118 | const stats = await compile()
119 |
120 | t.is(
121 | mfs.readFileSync('/import.wxml', 'utf8'),
122 | '\n \n \n'
123 | )
124 | t.is(
125 | mfs.readFileSync('/subdir/page.wxml', 'utf8'),
126 | '\n \n'
127 | )
128 |
129 | t.pass()
130 | })
131 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/transform.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 | import compiler from './helpers/compiler'
3 |
4 | test('use translations', async t => {
5 | const { compile, mfs } = compiler({
6 | entry: './fixtures/basic/page.mina',
7 | output: {
8 | filename: 'fixtures/basic/page.js',
9 | },
10 | module: {
11 | rules: [
12 | {
13 | test: /\.mina$/,
14 | use: {
15 | loader: require.resolve('..'),
16 | options: {
17 | transform: require('./helpers/transform/scope-id'),
18 | },
19 | },
20 | },
21 | ],
22 | },
23 | })
24 | const stats = await compile()
25 |
26 | t.deepEqual(stats.compilation.errors, [], stats.compilation.errors[0])
27 |
28 | t.true(mfs.existsSync('/assets/logo.72c9db.png'))
29 |
30 | t.true(
31 | mfs
32 | .readFileSync('/fixtures/basic/page.js', 'utf8')
33 | .includes('module.exports = "a2fce32d"')
34 | )
35 | t.is(mfs.readFileSync('/fixtures/basic/page.wxml', 'utf8'), 'a2fce32d')
36 | t.is(mfs.readFileSync('/fixtures/basic/page.wxss', 'utf8'), 'a2fce32d')
37 | t.is(mfs.readFileSync('/fixtures/basic/page.json', 'utf8'), 'a2fce32d')
38 |
39 | t.pass()
40 | })
41 |
--------------------------------------------------------------------------------
/packages/mina-loader/test/wxss.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 | import test from 'ava'
4 | import rimraf from 'rimraf'
5 | import compiler from './helpers/compiler'
6 |
7 | const fixture = p => path.join(__dirname, 'fixtures', p)
8 |
9 | const logo =
10 | 'image/png;base64,' +
11 | fs.readFileSync(fixture('basic/logo.png.txt'), 'utf8').trim()
12 |
13 | test.afterEach(() => {
14 | return new Promise(resolve => {
15 | rimraf(fixture('wxss/.dist'), () => resolve())
16 | })
17 | })
18 |
19 | test('url in wxss should be encoded as base64 inlined url by default', async t => {
20 | const { compile, mfs } = compiler({
21 | entry: './fixtures/wxss/page.mina',
22 | output: {
23 | filename: 'fixtures/wxss/page.js',
24 | },
25 | module: {
26 | rules: [
27 | {
28 | test: /\.mina$/,
29 | use: {
30 | loader: require.resolve('..'),
31 | },
32 | },
33 | ],
34 | },
35 | })
36 |
37 | const stats = await compile()
38 |
39 | t.is(
40 | mfs.readFileSync('/fixtures/wxss/page.wxss', 'utf8'),
41 | `text.blue {\n color: #00f;\n background: url(data:${logo});\n}`
42 | )
43 |
44 | t.pass()
45 | })
46 |
47 | test('url in wxss could be process with other inline url replacer', async t => {
48 | const { compile, mfs } = compiler({
49 | entry: './fixtures/wxss/page.mina',
50 | output: {
51 | filename: 'fixtures/wxss/page.js',
52 | },
53 | module: {
54 | rules: [
55 | {
56 | test: /\.mina$/,
57 | use: {
58 | loader: require.resolve('..'),
59 | options: {
60 | loaders: {
61 | style: {
62 | loader: 'postcss-loader',
63 | options: {
64 | config: {
65 | path: path.resolve(__dirname, './fixtures/wxss/url/'),
66 | },
67 | },
68 | },
69 | },
70 | },
71 | },
72 | },
73 | ],
74 | },
75 | })
76 |
77 | const stats = await compile()
78 |
79 | t.is(
80 | mfs.readFileSync('/fixtures/wxss/page.wxss', 'utf8'),
81 | `text.blue {\n color: #00f;\n background: url(data:${logo});\n}`
82 | )
83 |
84 | t.pass()
85 | })
86 |
87 | test('url in wxss could be process with other loaders', async t => {
88 | const { compile, mfs } = compiler({
89 | entry: './fixtures/wxss/page.mina',
90 | output: {
91 | filename: 'fixtures/wxss/page.js',
92 | },
93 | module: {
94 | rules: [
95 | {
96 | test: /\.mina$/,
97 | use: {
98 | loader: require.resolve('..'),
99 | options: {
100 | loaders: {
101 | style: {
102 | loader: 'postcss-loader',
103 | options: {
104 | config: {
105 | path: path.resolve(__dirname, './fixtures/wxss/cdn/'),
106 | },
107 | },
108 | },
109 | },
110 | },
111 | },
112 | },
113 | ],
114 | },
115 | })
116 |
117 | const stats = await compile()
118 |
119 | t.is(
120 | mfs.readFileSync('/fixtures/wxss/page.wxss', 'utf8'),
121 | `text.blue {\n color: #00f;\n background: url(https://cdn.url/logo_511d9d.png);\n}`
122 | )
123 |
124 | t.true(fs.existsSync(fixture('wxss/.dist/cdn/logo_511d9d.png')))
125 |
126 | t.pass()
127 | })
128 |
129 | test('disable base64 inlined by url in wxss ', async t => {
130 | const { compile, mfs } = compiler({
131 | entry: './fixtures/wxss/page.mina',
132 | output: {
133 | filename: 'fixtures/wxss/page.js',
134 | publicPath: 'https://cdn.url/',
135 | },
136 | module: {
137 | rules: [
138 | {
139 | test: /\.mina$/,
140 | use: {
141 | loader: require.resolve('..'),
142 | options: {
143 | useWxssUrl: false,
144 | },
145 | },
146 | },
147 | ],
148 | },
149 | })
150 |
151 | const stats = await compile()
152 |
153 | t.is(
154 | mfs.readFileSync('/fixtures/wxss/page.wxss', 'utf8'),
155 | `text.blue {\n color: #00f;\n background: url(https://cdn.url/assets/logo.72c9db.png);\n}`
156 | )
157 |
158 | t.pass()
159 | })
160 |
--------------------------------------------------------------------------------
/packages/mina-loader/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./lib",
4 | "forceConsistentCasingInFileNames": true,
5 | "esModuleInterop": true,
6 | "strict": true,
7 | "allowSyntheticDefaultImports": true,
8 | "listEmittedFiles": true,
9 | "listFiles": true,
10 | "allowJs": false,
11 | "declaration": true,
12 | "sourceMap": true,
13 | "target": "es6",
14 | "module": "commonjs"
15 | },
16 | "include": ["./src/**/*"]
17 | }
18 |
--------------------------------------------------------------------------------
/packages/mina-runtime-webpack-plugin/.gitignore:
--------------------------------------------------------------------------------
1 | lib/
2 |
--------------------------------------------------------------------------------
/packages/mina-runtime-webpack-plugin/.lintstagedrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "linters": {
3 | "*.{md,js,json}": ["prettier --write", "git add"]
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/mina-runtime-webpack-plugin/.prettierrc.js:
--------------------------------------------------------------------------------
1 | // @see https://prettier.io/docs/en/options.html
2 | module.exports = {
3 | semi: false,
4 | singleQuote: true,
5 | trailingComma: 'es5',
6 | }
7 |
--------------------------------------------------------------------------------
/packages/mina-runtime-webpack-plugin/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 - present, yelo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/packages/mina-runtime-webpack-plugin/README.md:
--------------------------------------------------------------------------------
1 | # mina-runtime-webpack-plugin
2 |
3 | > A runtime patch for compiling mina project by [Webpack](https://webpack.js.org/).
4 |
5 | [](https://www.npmjs.com/package/@tinajs/mina-runtime-webpack-plugin)
6 | [](https://www.npmjs.com/package/@tinajs/mina-runtime-webpack-plugin)
7 | [](./LICENSE)
8 | [](http://makeapullrequest.com)
9 |
10 | _Heavily inspired by and forked from [Cap32/wxapp-webpack-plugin](https://github.com/Cap32/wxapp-webpack-plugin)._
11 |
12 | ## Installation
13 |
14 | ```bash
15 | npm i --save-dev @tinajs/mina-runtime-webpack-plugin
16 | ```
17 |
18 | ## Usage
19 |
20 | ```javascript
21 | /**
22 | * webpack.config.js
23 | */
24 | const webpack = require('webpack')
25 | const MinaRuntimePlugin = require('@tinajs/mina-runtime-webpack-plugin')
26 |
27 | const resolve = require('path').resolve
28 |
29 | module.exports = {
30 | context: resolve('src'),
31 | entry: {
32 | 'app.mina': './app.mina',
33 | 'pages/home.mina': './pages/home.mina',
34 | },
35 | output: {
36 | path: resolve('dist'),
37 | filename: '[name]',
38 | publicPath: '/',
39 | globalObject: 'wx',
40 | },
41 | module: {
42 | rules: [
43 | {
44 | test: /\.mina$/,
45 | use: {
46 | loader: '@tinajs/mina-loader',
47 | },
48 | },
49 | ],
50 | },
51 | plugins: [new MinaRuntimePlugin()],
52 | optimization: {
53 | splitChunks: {
54 | chunks: 'all',
55 | name: 'common.js',
56 | minChunks: 2,
57 | minSize: 0,
58 | },
59 | runtimeChunk: {
60 | name: 'runtime.js',
61 | },
62 | },
63 | mode: 'none',
64 | }
65 | ```
66 |
67 | For the best particle, you might also be interested in [mina-webpack](https://github.com/tinajs/mina-webpack/).
68 |
69 | ## Example
70 |
71 | - [mina-webpack - Full Example](https://github.com/tinajs/mina-webpack/tree/master/example)
72 | - [TinaJS - HackerNews Reader](https://github.com/tinajs/tina-hackernews)
73 |
74 | ## License
75 |
76 | MIT © [yelo](https://github.com/imyelo), 2017 - present
77 |
--------------------------------------------------------------------------------
/packages/mina-runtime-webpack-plugin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@tinajs/mina-runtime-webpack-plugin",
3 | "version": "1.3.7",
4 | "description": "A runtime patch for compiling mina project by Webpack",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "clean": "rimraf lib",
8 | "precommit": "lint-staged",
9 | "prebuild": "npm run clean",
10 | "prepare": "npm run build",
11 | "build": "tsc -p ."
12 | },
13 | "author": "yelo",
14 | "license": "MIT",
15 | "publishConfig": {
16 | "access": "public"
17 | },
18 | "repository": {
19 | "url": "tinajs/mina-webpack",
20 | "type": "git"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/tinajs/mina-webpack/issues"
24 | },
25 | "homepage": "https://github.com/tinajs/mina-webpack/tree/master/packages/mina-runtime-webpack-plugin#readme",
26 | "dependencies": {
27 | "debug": "^4.1.1",
28 | "ensure-posix-path": "^1.1.1",
29 | "required-path": "^1.0.1",
30 | "webpack-sources": "^1.3.0"
31 | },
32 | "devDependencies": {
33 | "@types/debug": "^4.1.5",
34 | "@types/node": "^12.7.1",
35 | "@types/webpack": "^4.32.1",
36 | "@types/webpack-sources": "^0.1.5",
37 | "lint-staged": "^13.1.0",
38 | "prettier": "^1.19.1",
39 | "typescript": "^3.8.3"
40 | },
41 | "gitHead": "1be88492c3caad72b677320eb61d5774f2d480cc"
42 | }
43 |
--------------------------------------------------------------------------------
/packages/mina-runtime-webpack-plugin/polyfill.js:
--------------------------------------------------------------------------------
1 | //
2 | // Inject missing variables back
3 | // into the global object
4 | // (used by corejs in the Wechat-Mini-Program environment)
5 | //
6 | // see:
7 | // - https://github.com/zloirock/core-js/blob/0b4981/packages/core-js/internals/global.js
8 | //
9 | ;(function() {
10 | try {
11 | var global = new Function('return this')()
12 |
13 | function polyfill(name, value) {
14 | if (!global[name]) {
15 | global[name] = value
16 | }
17 | }
18 |
19 | polyfill('parseInt', parseInt)
20 | polyfill('parseFloat', parseFloat)
21 | } catch (e) {}
22 | })()
23 |
--------------------------------------------------------------------------------
/packages/mina-runtime-webpack-plugin/src/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * forked from https://github.com/Cap32/wxapp-webpack-plugin/
3 | */
4 | import webpack from 'webpack'
5 | import fs from 'fs'
6 | import path from 'path'
7 | import ensurePosix from 'ensure-posix-path'
8 | import { ConcatSource } from 'webpack-sources'
9 | // @ts-ignore
10 | import requiredPath from 'required-path'
11 | import Debug from 'debug'
12 |
13 | const debug = Debug('plugins:mina-runtime')
14 |
15 | function isRuntimeExtracted(compilation: webpack.compilation.Compilation) {
16 | return compilation.chunks.some(
17 | chunk =>
18 | chunk.isOnlyInitial() && chunk.hasRuntime() && !chunk.hasEntryModule()
19 | )
20 | }
21 |
22 | function script({ dependencies }: { dependencies: Array }) {
23 | return (
24 | ';' + dependencies.map(file => `require('${requiredPath(file)}');`).join('')
25 | )
26 | }
27 |
28 | const POLYFILL = fs.readFileSync(path.join(__dirname, '../polyfill.js'), 'utf8')
29 |
30 | module.exports = class MinaRuntimeWebpackPlugin implements webpack.Plugin {
31 | runtime: string
32 |
33 | constructor(options: { runtime?: string } = {}) {
34 | this.runtime = options.runtime || ''
35 | }
36 |
37 | apply(compiler: webpack.Compiler) {
38 | compiler.hooks.compilation.tap('MinaRuntimePlugin', compilation => {
39 | // @ts-ignore
40 | compilation.chunkTemplate.hooks.renderWithEntry.tap(
41 | 'MinaRuntimePlugin',
42 | (source: any, entry: webpack.compilation.Chunk) => {
43 | if (!isRuntimeExtracted(compilation)) {
44 | throw new Error(
45 | [
46 | 'Please reuse the runtime chunk to avoid duplicate loading of javascript files.',
47 | "Simple solution: set `optimization.runtimeChunk` to `{ name: 'runtime.js' }` .",
48 | 'Detail of `optimization.runtimeChunk`: https://webpack.js.org/configuration/optimization/#optimization-runtimechunk .',
49 | ].join('\n')
50 | )
51 | }
52 | if (!entry.hasEntryModule()) {
53 | return source
54 | }
55 |
56 | let dependencies: Array = []
57 | entry.groupsIterable.forEach(group => {
58 | group.chunks.forEach((chunk: webpack.compilation.Chunk) => {
59 | /**
60 | * assume output.filename is chunk.name here
61 | */
62 | let filename = ensurePosix(
63 | path.relative(path.dirname(entry.name), chunk.name)
64 | )
65 | if (chunk === entry || ~dependencies.indexOf(filename)) {
66 | return
67 | }
68 | dependencies.push(filename)
69 | })
70 | })
71 | debug(`dependencies of ${entry.name}:`, dependencies)
72 | source = new ConcatSource(script({ dependencies }), source)
73 | return source
74 | }
75 | )
76 |
77 | // @ts-ignore
78 | compilation.mainTemplate.hooks.bootstrap.tap(
79 | 'MinaRuntimePlugin',
80 | (source: any, chunk: webpack.compilation.Chunk) => {
81 | debug('bootstrap chunk name', chunk.name)
82 | return POLYFILL + source
83 | }
84 | )
85 | })
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/packages/mina-runtime-webpack-plugin/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./lib",
4 | "forceConsistentCasingInFileNames": true,
5 | "esModuleInterop": true,
6 | "strict": true,
7 | "allowSyntheticDefaultImports": true,
8 | "listEmittedFiles": true,
9 | "listFiles": true,
10 | "allowJs": false,
11 | "declaration": true,
12 | "sourceMap": true,
13 | "target": "es6",
14 | "module": "commonjs"
15 | },
16 | "include": ["./src/**/*"]
17 | }
18 |
--------------------------------------------------------------------------------
/packages/wxs-loader/.gitignore:
--------------------------------------------------------------------------------
1 | lib/
2 |
--------------------------------------------------------------------------------
/packages/wxs-loader/.lintstagedrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "linters": {
3 | "*.{md,js,json}": ["prettier --write", "git add"]
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/wxs-loader/.prettierrc.js:
--------------------------------------------------------------------------------
1 | // @see https://prettier.io/docs/en/options.html
2 | module.exports = {
3 | semi: false,
4 | singleQuote: true,
5 | trailingComma: 'es5',
6 | }
7 |
--------------------------------------------------------------------------------
/packages/wxs-loader/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/packages/wxs-loader/README.md:
--------------------------------------------------------------------------------
1 | # wxs-loader
2 |
3 | > [wxs](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/01wxs-module.html) loader for [Webpack](https://webpack.js.org/).
4 |
5 | [](https://www.npmjs.com/package/@tinajs/wxs-loader)
6 | [](https://www.npmjs.com/package/@tinajs/wxs-loader)
7 | [](./LICENSE)
8 | [](http://makeapullrequest.com)
9 |
10 | ## Installation
11 |
12 | ```bash
13 | npm i --save-dev @tinajs/wxs-loader
14 | ```
15 |
16 | ## Usage
17 |
18 | ```javascript
19 | /**
20 | * webpack.config.js
21 | */
22 | module.exports = {
23 | context: resolve('src'),
24 | mode: 'production',
25 | entry: {
26 | 'app.mina': './app.mina',
27 | },
28 | output: {
29 | path: resolve('dist'),
30 | filename: '[name]',
31 | publicPath: '/',
32 | },
33 | module: {
34 | rules: [
35 | {
36 | test: /\.mina$/,
37 | use: {
38 | loader: '@tinajs/mina-loader',
39 | },
40 | },
41 | {
42 | test: /\.wxs$/,
43 | use: [
44 | {
45 | loader: '@tinajs/wxs-loader',
46 | options: {
47 | name: 'wxs/[name].[hash:6].[ext]',
48 | },
49 | },
50 | ],
51 | },
52 | ],
53 | },
54 | }
55 | ```
56 |
57 | For the best particle, you might also be interested in [mina-webpack](https://github.com/tinajs/mina-webpack/).
58 |
59 | ## Options
60 |
61 | | Name | Default | Description |
62 | | ------- | -------------- | ----------------------------------------------------------------------------------------------------------- |
63 | | name | `[hash].[ext]` | Custom filename template, same as [file-loader - name](https://github.com/webpack-contrib/file-loader#name) |
64 | | context | `context` | Same as [file-loader - context](https://github.com/webpack-contrib/file-loader#context) |
65 | | regExp | `undefined` | Same as [file-loader - regExp](https://github.com/webpack-contrib/file-loader#regexp) |
66 |
67 | ## Example
68 |
69 | - [mina-webpack - Full Example](https://github.com/tinajs/mina-webpack/tree/master/example)
70 | - [wxs-loader - test](https://github.com/tinajs/mina-webpack/tree/master/packages/wxs-loader/test)
71 |
72 | ## License
73 |
74 | Apache-2.0 © [yelo](https://github.com/imyelo), 2018 - present
75 |
--------------------------------------------------------------------------------
/packages/wxs-loader/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@tinajs/wxs-loader",
3 | "version": "1.2.12",
4 | "description": "wxs loader for webpack",
5 | "main": "lib/index.js",
6 | "files": [
7 | "lib"
8 | ],
9 | "scripts": {
10 | "clean": "rimraf lib",
11 | "prebuild": "npm run clean",
12 | "precommit": "lint-staged",
13 | "prepare": "npm run build",
14 | "build": "tsc -p .",
15 | "test": "ava test/*.js"
16 | },
17 | "author": "yelo",
18 | "license": "Apache-2.0",
19 | "publishConfig": {
20 | "access": "public"
21 | },
22 | "repository": {
23 | "url": "tinajs/mina-webpack",
24 | "type": "git"
25 | },
26 | "bugs": {
27 | "url": "https://github.com/tinajs/mina-webpack/issues"
28 | },
29 | "homepage": "https://github.com/tinajs/mina-webpack/tree/master/packages/mina-loader#readme",
30 | "devDependencies": {
31 | "@types/node": "^11.9.6",
32 | "ava": "^5.3.1",
33 | "file-loader": "^6.2.0",
34 | "lint-staged": "^13.1.0",
35 | "memory-fs": "^0.4.1",
36 | "prettier": "^1.19.1",
37 | "typescript": "^3.8.3",
38 | "webpack": "^5.75.0",
39 | "webpack-chain": "^5.2.0"
40 | },
41 | "peerDependencies": {
42 | "webpack": "^4.0.0"
43 | },
44 | "dependencies": {
45 | "@babel/core": "^7.3.4",
46 | "co": "^4.6.0",
47 | "ensure-posix-path": "^1.1.1",
48 | "loader-utils": "^3.2.1",
49 | "required-path": "^1.0.1"
50 | },
51 | "gitHead": "1be88492c3caad72b677320eb61d5774f2d480cc"
52 | }
53 |
--------------------------------------------------------------------------------
/packages/wxs-loader/src/helpers/extract.js:
--------------------------------------------------------------------------------
1 | const vm = require('vm')
2 | /**
3 | * Forked from:
4 | * https://github.com/peerigon/extract-loader/blob/f5a1946a7b54ef962e5af56aaf29d318efaabf66/src/extractLoader.js#L110
5 | * https://github.com/Cap32/wxml-loader/blob/986c2a07f195c0f8f4e35169148e4965061a50f6/src/index.js#L21
6 | */
7 | module.exports = function(src, publicPath = '') {
8 | const script = new vm.Script(src, {
9 | displayErrors: true,
10 | })
11 | const sandbox = {
12 | module: {},
13 | __webpack_public_path__: publicPath,
14 | }
15 |
16 | script.runInNewContext(sandbox)
17 | return sandbox.module.exports.toString()
18 | }
19 |
--------------------------------------------------------------------------------
/packages/wxs-loader/src/helpers/get-public-path.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Retrieves the public path from the loader options, context.options (webpack <4) or context._compilation (webpack 4+).
3 | * context._compilation is likely to get removed in a future release, so this whole function should be removed then.
4 | * See: https://github.com/peerigon/extract-loader/issues/35
5 | *
6 | * @deprecated
7 | * @param {Object} options - Extract-loader options
8 | * @param {Object} context - Webpack loader context
9 | * @returns {string}
10 | */
11 | module.exports = function getPublicPath(options, context) {
12 | const property = 'publicPath'
13 |
14 | if (property in options) {
15 | return options[property]
16 | }
17 |
18 | if (
19 | context.options &&
20 | context.options.output &&
21 | property in context.options.output
22 | ) {
23 | return context.options.output[property]
24 | }
25 |
26 | if (
27 | context._compilation &&
28 | context._compilation.outputOptions &&
29 | property in context._compilation.outputOptions
30 | ) {
31 | return context._compilation.outputOptions[property]
32 | }
33 |
34 | return ''
35 | }
36 |
--------------------------------------------------------------------------------
/packages/wxs-loader/src/helpers/load-module.js:
--------------------------------------------------------------------------------
1 | module.exports = function loadModule(ctx, request) {
2 | return new Promise((resolve, reject) => {
3 | ctx.loadModule(request, (err, source) => {
4 | if (err) {
5 | return reject(err)
6 | }
7 | resolve(source)
8 | })
9 | })
10 | }
11 |
--------------------------------------------------------------------------------
/packages/wxs-loader/src/helpers/relative.js:
--------------------------------------------------------------------------------
1 | const { relative, dirname } = require('path')
2 | const requiredPath = require('required-path')
3 | const posix = require('ensure-posix-path')
4 |
5 | module.exports = (fromFile, toFile) =>
6 | posix(requiredPath(relative(dirname(fromFile), toFile)))
7 |
--------------------------------------------------------------------------------
/packages/wxs-loader/src/helpers/resolve.js:
--------------------------------------------------------------------------------
1 | module.exports = function resolve(ctx, request) {
2 | return new Promise((resolve, reject) => {
3 | ctx.resolve(ctx.context, request, (err, result) => {
4 | if (err) {
5 | return reject(err)
6 | }
7 | resolve(result)
8 | })
9 | })
10 | }
11 |
--------------------------------------------------------------------------------
/packages/wxs-loader/src/helpers/to-safe-output-path.js:
--------------------------------------------------------------------------------
1 | const toSafeOutputPath = (original) => {
2 | return (original || '')
3 | .replace(/\.\./g, '_')
4 | .replace(/node_modules([\/\\])/g, '_node_modules_$1')
5 | }
6 |
7 | module.exports = toSafeOutputPath
8 |
--------------------------------------------------------------------------------
/packages/wxs-loader/src/helpers/visit.js:
--------------------------------------------------------------------------------
1 | const babel = require('@babel/core')
2 |
3 | const visit = (source, visitor) =>
4 | babel.transform(source, {
5 | babelrc: false,
6 | configFile: false,
7 | plugins: [
8 | ({ types: t }) => {
9 | return {
10 | name: 'wxs collector',
11 | visitor: visitor(t),
12 | }
13 | },
14 | ],
15 | })
16 |
17 | module.exports = visit
18 |
--------------------------------------------------------------------------------
/packages/wxs-loader/src/index.js:
--------------------------------------------------------------------------------
1 | const utils = require('loader-utils')
2 | const extract = require('./helpers/extract')
3 | const getPublicPath = require('./helpers/get-public-path')
4 | const loadModule = require('./helpers/load-module')
5 | const relative = require('./helpers/relative')
6 | const resolve = require('./helpers/resolve')
7 | const visit = require('./helpers/visit')
8 | const toSafeOutputPath = require('./helpers/to-safe-output-path')
9 |
10 | module.exports = function loader(source) {
11 | const done = this.async()
12 | const options = Object.assign(
13 | {},
14 | {
15 | name: '[hash].[ext]',
16 | context: this.rootContext,
17 | regExp: void 0,
18 | },
19 | utils.getOptions(this)
20 | )
21 | const publicPath = getPublicPath({}, this)
22 | const interpolateName = (content = 'PLACEHOLDER') =>
23 | toSafeOutputPath(utils.interpolateName(this, options.name, {
24 | content,
25 | context: options.context,
26 | regExp: options.regExp,
27 | }))
28 |
29 | let dependencies = new Map()
30 |
31 | // find untransformed dependencies
32 | visit(source, () => ({
33 | CallExpression(path) {
34 | if (path.node.callee.name === 'require') {
35 | dependencies.set(path.node.arguments[0].value)
36 | }
37 | },
38 | }))
39 |
40 | // generate a mock filename with placeholder input
41 | let target = interpolateName()
42 |
43 | Promise.resolve()
44 | // transform dependencies's pathes
45 | .then(() =>
46 | Promise.all(
47 | Array.from(dependencies.keys()).map(dependency =>
48 | resolve(this, dependency)
49 | .then(path => loadModule(this, path))
50 | .then(code => extract(code, publicPath))
51 | .then(dest => {
52 | this.addDependency(dependency)
53 | dependencies.set(dependency, relative(publicPath + target, dest))
54 | })
55 | )
56 | )
57 | )
58 | .then(() => {
59 | // generate code with transformed dependencies's pathes
60 | let { code } = visit(source, t => ({
61 | CallExpression(path) {
62 | if (path.node.callee.name === 'require') {
63 | path.node.arguments[0] = t.stringLiteral(
64 | dependencies.get(path.node.arguments[0].value)
65 | )
66 | }
67 | },
68 | }))
69 | // generate the correct filename
70 | target = interpolateName(code)
71 |
72 | // emit file
73 | this.emitFile(target, code)
74 |
75 | // and also export the filename in the form of javascript
76 | done(
77 | null,
78 | `module.exports = __webpack_public_path__ + ${JSON.stringify(target)}`
79 | )
80 | })
81 | .catch(error => done(error))
82 | }
83 |
--------------------------------------------------------------------------------
/packages/wxs-loader/test/fixtures/constants.wxs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | EEVEE: 133,
3 | }
4 |
--------------------------------------------------------------------------------
/packages/wxs-loader/test/fixtures/greet.wxs:
--------------------------------------------------------------------------------
1 | module.exports = function (no) {
2 | return 'No.' + no
3 | }
4 |
--------------------------------------------------------------------------------
/packages/wxs-loader/test/fixtures/padding.wxs:
--------------------------------------------------------------------------------
1 | import constants from './constants.wxs'
2 |
3 | const padding = (digits) => {
4 | return function pad (number) {
5 | var ceil = Math.pow(10, digits) + number;
6 | return ceil.toString().slice(1);
7 | };
8 | };
9 |
10 | module.exports = padding;
11 |
--------------------------------------------------------------------------------
/packages/wxs-loader/test/fixtures/pokemon/eevee.wxs:
--------------------------------------------------------------------------------
1 | const constants = require('../constants.wxs')
2 | const greet = require('../greet.wxs')
3 |
4 | module.exports = greet(constants.EEVEE)
5 |
--------------------------------------------------------------------------------
/packages/wxs-loader/test/helpers/compiler.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import webpack from 'webpack'
3 | import Config from 'webpack-chain'
4 | import MemoryFS from 'memory-fs'
5 |
6 | const root = path.resolve(__dirname, '..')
7 |
8 | export default (use = () => {}) => {
9 | const mfs = new MemoryFS()
10 | const config = new Config()
11 |
12 | config.mode('none').context(root)
13 |
14 | config.output.path('/').publicPath('/')
15 |
16 | config.module
17 | .rule('wxs')
18 | .test(/\.wxs$/)
19 | .use('wxs')
20 | .loader(require.resolve('../..'))
21 | .options({
22 | name: 'assets/[name].[hash:6].[ext]',
23 | })
24 | .end()
25 |
26 | use(config)
27 |
28 | return {
29 | mfs,
30 | compile() {
31 | const compiler = webpack(config.toConfig())
32 | compiler.outputFileSystem = mfs
33 | return new Promise((resolve, reject) =>
34 | compiler.run((err, stats) => {
35 | if (err) {
36 | return reject(err)
37 | }
38 | resolve(stats)
39 | })
40 | )
41 | },
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/packages/wxs-loader/test/snapshots/wxs.js.snap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinajs/mina-webpack/954761f689772903fd7b2d3f83d1493435818076/packages/wxs-loader/test/snapshots/wxs.js.snap
--------------------------------------------------------------------------------
/packages/wxs-loader/test/wxs.js:
--------------------------------------------------------------------------------
1 | import { resolve } from 'path'
2 | import test from 'ava'
3 | import compiler from './helpers/compiler'
4 |
5 | const noop = () => {}
6 |
7 | const macros = {
8 | async webpack(t, config = noop, test = noop) {
9 | const { compile, mfs } = compiler(config)
10 | const stats = await compile()
11 |
12 | t.is(stats.compilation.errors.length, 0, stats.compilation.errors)
13 |
14 | t.snapshot(mfs)
15 |
16 | test(t, mfs)
17 | },
18 | }
19 |
20 | test(
21 | 'require',
22 | macros.webpack,
23 | config => {
24 | config.entry('entry').add('./fixtures/pokemon/eevee.wxs')
25 | },
26 | (t, mfs) => {
27 | t.true(mfs.existsSync('/assets/eevee.767a51.wxs', 'utf8'))
28 | t.true(mfs.existsSync('/assets/constants.39caca.wxs', 'utf8'))
29 | t.true(mfs.existsSync('/assets/greet.e4c88c.wxs', 'utf8'))
30 |
31 | t.is(
32 | mfs.readFileSync('/assets/eevee.767a51.wxs', 'utf8'),
33 | 'const constants = require("./constants.39caca.wxs");\n\nconst greet = require("./greet.e4c88c.wxs");\n\nmodule.exports = greet(constants.EEVEE);'
34 | )
35 |
36 | t.pass()
37 | }
38 | )
39 |
40 | test(
41 | 'default options',
42 | macros.webpack,
43 | config => {
44 | config.entry('entry').add('./fixtures/pokemon/eevee.wxs')
45 | config.module
46 | .rule('wxs')
47 | .use('wxs')
48 | .options()
49 | },
50 | (t, mfs) => {
51 | t.true(mfs.existsSync('/f3316048fe61f33a4f884ffc07e9e8eb.wxs', 'utf8'))
52 | t.true(mfs.existsSync('/39caca0fd21f51bcb712120d36ae59b3.wxs', 'utf8'))
53 | t.true(mfs.existsSync('/e4c88c228f3f9a32551be1979d11a078.wxs', 'utf8'))
54 |
55 | t.is(
56 | mfs.readFileSync('/f3316048fe61f33a4f884ffc07e9e8eb.wxs', 'utf8'),
57 | 'const constants = require("./39caca0fd21f51bcb712120d36ae59b3.wxs");\n\nconst greet = require("./e4c88c228f3f9a32551be1979d11a078.wxs");\n\nmodule.exports = greet(constants.EEVEE);'
58 | )
59 |
60 | t.pass()
61 | }
62 | )
63 |
64 | test(
65 | 'custom options: name, regExp',
66 | macros.webpack,
67 | config => {
68 | config.entry('entry').add('./fixtures/pokemon/eevee.wxs')
69 | config.module
70 | .rule('wxs')
71 | .use('wxs')
72 | .options({
73 | name: '[1]/[path]/[name].[hash:6].[ext]',
74 | regExp: /\.(\w+)$/,
75 | })
76 | },
77 | (t, mfs) => {
78 | t.true(mfs.existsSync('/wxs/fixtures/pokemon/eevee.347ed5.wxs', 'utf8'))
79 | t.true(mfs.existsSync('/wxs/fixtures/constants.39caca.wxs', 'utf8'))
80 | t.true(mfs.existsSync('/wxs/fixtures/greet.e4c88c.wxs', 'utf8'))
81 |
82 | t.is(
83 | mfs.readFileSync('/wxs/fixtures/pokemon/eevee.347ed5.wxs', 'utf8'),
84 | 'const constants = require("./../constants.39caca.wxs");\n\nconst greet = require("./../greet.e4c88c.wxs");\n\nmodule.exports = greet(constants.EEVEE);'
85 | )
86 |
87 | t.pass()
88 | }
89 | )
90 |
91 | test(
92 | 'custom options: name, regExp, context',
93 | macros.webpack,
94 | config => {
95 | config.entry('entry').add('./fixtures/pokemon/eevee.wxs')
96 | config.module
97 | .rule('wxs')
98 | .use('wxs')
99 | .options({
100 | name: '[1]/[path]/[name].[hash:6].[ext]',
101 | regExp: /\.(\w+)$/,
102 | context: resolve(__dirname, './fixtures/'),
103 | })
104 | },
105 | (t, mfs) => {
106 | t.true(mfs.existsSync('/wxs/pokemon/eevee.347ed5.wxs', 'utf8'))
107 | t.true(mfs.existsSync('/wxs/constants.39caca.wxs', 'utf8'))
108 | t.true(mfs.existsSync('/wxs/greet.e4c88c.wxs', 'utf8'))
109 |
110 | t.is(
111 | mfs.readFileSync('/wxs/pokemon/eevee.347ed5.wxs', 'utf8'),
112 | 'const constants = require("./../constants.39caca.wxs");\n\nconst greet = require("./../greet.e4c88c.wxs");\n\nmodule.exports = greet(constants.EEVEE);'
113 | )
114 |
115 | t.pass()
116 | }
117 | )
118 |
--------------------------------------------------------------------------------
/packages/wxs-loader/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./lib",
4 | "forceConsistentCasingInFileNames": true,
5 | "esModuleInterop": true,
6 | "strict": true,
7 | "allowSyntheticDefaultImports": true,
8 | "allowJs": true,
9 | "target": "es6",
10 | "module": "commonjs"
11 | },
12 | "include": ["./src/**/*"]
13 | }
14 |
--------------------------------------------------------------------------------