Skip to content
This repository was archived by the owner on May 7, 2024. It is now read-only.

Commit c0b8ab5

Browse files
authored
Merge pull request NightlyCommit#18 from ericmorand/issue_17
Fis issue NightlyCommit#17
2 parents 82a1258 + 099455c commit c0b8ab5

File tree

15 files changed

+443
-681
lines changed

15 files changed

+443
-681
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
dist
44
coverage
55
node_modules
6-
package-lock.json
6+
package-lock.json
7+
tmp

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# twing-loader
22
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage percentage][coveralls-image]][coveralls-url]
33

4-
Webpack loader that compiles Twig templates using [Twing](https://www.npmjs.com/package/twing).
4+
Webpack loader for Twig templates, based on [Twing](https://www.npmjs.com/package/twing).
55

66
## Prerequisites
77

88
* Webpack 4
9-
* Twing 2.3.3
9+
* Twing 3.0.1
1010

1111
## Installation
1212

package.json

+5-6
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
],
3434
"license": "ISC",
3535
"peerDependencies": {
36-
"twing": "^2.3.3"
36+
"twing": "^3.0.1"
3737
},
3838
"repository": {
3939
"type": "git",
@@ -43,12 +43,11 @@
4343
"url": "https://github.com/NightlyCommit/twing-loader/issues"
4444
},
4545
"homepage": "https://github.com/NightlyCommit/twing-loader#readme",
46-
"description": "",
46+
"description": "Webpack loader for Twig templates, based on Twing.",
4747
"dependencies": {
4848
"crypto-js": "^3.1.9-1",
4949
"loader-utils": "^1.2.3",
50-
"schema-utils": "^2.2.0",
51-
"slash": "^3.0.0"
50+
"schema-utils": "^2.2.0"
5251
},
5352
"devDependencies": {
5453
"@types/loader-utils": "^1.1.3",
@@ -63,14 +62,14 @@
6362
"memory-fs": "^0.4.1",
6463
"module-alias": "^2.2.1",
6564
"nyc": "^14.1.1",
66-
"slash": "^3.0.0",
6765
"rimraf": "^2.7.1",
6866
"sinon": "^7.5.0",
67+
"slash": "^3.0.0",
6968
"tap-bail": "^1.0.0",
7069
"tap-spec": "^5.0.0",
7170
"tape": "^4.11.0",
7271
"ts-node": "^8.4.1",
73-
"twing": "^2.3.6",
72+
"twing": "^3.0.1",
7473
"typescript": "^3.6.3",
7574
"webpack": "^4.41.0",
7675
"webpack-cli": "^3.3.9"

src/index.ts

+39-45
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import {getOptions} from 'loader-utils';
22
import {loader} from 'webpack';
3-
import {TwingEnvironment, TwingLoaderArray, TwingLoaderChain, TwingSource} from 'twing';
4-
import {NodeVisitor} from "./node-visitor";
3+
import {
4+
TwingEnvironment,
5+
TwingLoaderArray,
6+
TwingLoaderChain,
7+
TwingNodeModule,
8+
TwingSource, TwingTokenStream
9+
} from 'twing';
10+
import {Visitor} from "./visitor";
511

612
const sha256 = require('crypto-js/sha256');
713
const hex = require('crypto-js/enc-hex');
8-
const process = require('process');
914
const slash = require('slash');
1015

1116
const validateOptions = require('schema-utils');
@@ -27,82 +32,71 @@ const optionsSchema = {
2732
};
2833

2934
class PathSupportingArrayLoader extends TwingLoaderArray {
30-
getSourceContext(name: string): TwingSource {
31-
let source = super.getSourceContext(name);
35+
getSourceContext(name: string, from: TwingSource): TwingSource {
36+
let source = super.getSourceContext(name, from);
3237

3338
return new TwingSource(source.getCode(), source.getName(), name);
3439
}
3540
}
3641

3742
export default function (this: loader.LoaderContext, source: string) {
43+
const getTemplateHash = (name: string) => {
44+
return this.mode !== 'production' ? name : hex.stringify(sha256(name));
45+
};
46+
3847
const options = getOptions(this);
3948

4049
validateOptions(optionsSchema, options, 'Twing loader');
4150

4251
let resourcePath: string = slash(this.resourcePath);
43-
let environmentModulePath: string = slash(options.environmentModulePath);
52+
let environmentModulePath: string = options.environmentModulePath;
4453
let renderContext: any = options.renderContext;
4554

46-
this.addDependency(environmentModulePath);
47-
48-
// we don't want to reuse an eventual initialized environment
49-
delete require.cache[require.resolve(environmentModulePath)];
55+
this.addDependency(slash(environmentModulePath));
5056

51-
let environment: TwingEnvironment = require(environmentModulePath);
57+
// require takes module name separated wicth forward slashes
58+
let environment: TwingEnvironment = require(slash(environmentModulePath));
59+
let loader = environment.getLoader();
5260

5361
if (renderContext === undefined) {
54-
5562
let parts: string[] = [
56-
`const {cache, loader, getEnvironment} = require('${slash(require.resolve('./runtime'))}');`,
57-
`const env = getEnvironment(require('${environmentModulePath}'));`
63+
`const env = require('${slash(environmentModulePath)}');`
5864
];
5965

60-
let nodeVisitor: NodeVisitor;
61-
62-
nodeVisitor = new NodeVisitor();
63-
nodeVisitor.fromPath = resourcePath;
66+
let key = getTemplateHash(resourcePath);
67+
let sourceContext: TwingSource = new TwingSource(source, `${key}`);
68+
let tokenStream: TwingTokenStream = environment.tokenize(sourceContext);
6469

65-
environment.addNodeVisitor(nodeVisitor);
70+
let module: TwingNodeModule = environment.parse(tokenStream);
6671

67-
Reflect.set(environment, 'getTemplateClass', function (name: string, index: number = null, from: TwingSource = null) {
68-
let hash: string;
72+
let visitor = new Visitor(loader, resourcePath, getTemplateHash);
6973

70-
const HASH_PREFIX = '__HASHED__';
74+
visitor.visit(module);
7175

72-
if (name.startsWith(HASH_PREFIX)) {
73-
hash = name;
74-
} else {
75-
hash = `${HASH_PREFIX}${hex.stringify(sha256(name))}`;
76-
}
76+
let precompiledTemplate = environment.compile(module);
7777

78-
return hash + (index === null ? '' : '_' + index);
79-
});
80-
81-
let className: string = environment.getTemplateClass(resourcePath);
82-
let sourceContext: TwingSource = new TwingSource(source, className);
83-
let precompiledTemplate = environment.compile(environment.parse(environment.tokenize(sourceContext)));
84-
85-
parts.push(`cache.write('${className}', (() => {let module = {
78+
parts.push(`let templatesModule = (() => {
79+
let module = {
8680
exports: undefined
8781
};
8882
8983
${precompiledTemplate}
9084
91-
return module.exports;})());
85+
return module.exports;
86+
})();
9287
`);
93-
parts.push(`loader.addTemplateKey('${className}', '${className}');`);
9488

95-
for (let foundTemplateName of nodeVisitor.foundTemplateNames) {
96-
if (process.platform === 'win32') {
97-
foundTemplateName = slash(foundTemplateName);
98-
}
99-
parts.push(`require('${foundTemplateName}');`);
89+
for (let foundTemplateName of visitor.foundTemplateNames) {
90+
// require takes module name separated with forward slashes
91+
parts.push(`require('${slash(foundTemplateName)}');`);
10092
}
10193

94+
parts.push(`env.registerTemplatesModule(templatesModule, '${key}');`);
95+
10296
parts.push(`
103-
let template = env.loadTemplate('${className}');
97+
let template = env.loadTemplate('${key}');
10498
105-
module.exports = function(context = {}) {
99+
module.exports = (context = {}) => {
106100
return template.render(context);
107101
};`);
108102

@@ -112,7 +106,7 @@ module.exports = function(context = {}) {
112106
new PathSupportingArrayLoader(new Map([
113107
[resourcePath, source]
114108
])),
115-
environment.getLoader()
109+
loader
116110
]));
117111

118112
environment.on('template', (name: string, from: TwingSource) => {

src/node-visitor.ts

-90
This file was deleted.

0 commit comments

Comments
 (0)